diff options
682 files changed, 26191 insertions, 20232 deletions
@@ -7,3 +7,4 @@ cscope.out *.pyc *~ .*.swp +m5out diff --git a/SConstruct b/SConstruct index 85c5de142..dac317fe8 100644 --- a/SConstruct +++ b/SConstruct @@ -96,6 +96,7 @@ For more details, see: """ raise +# Global Python includes import os import re import subprocess @@ -106,55 +107,18 @@ from os.path import abspath, basename, dirname, expanduser, normpath from os.path import exists, isdir, isfile from os.path import join as joinpath, split as splitpath +# SCons includes import SCons import SCons.Node -def read_command(cmd, **kwargs): - """run the command cmd, read the results and return them - this is sorta like `cmd` in shell""" - from subprocess import Popen, PIPE, STDOUT - - if isinstance(cmd, str): - cmd = cmd.split() - - no_exception = 'exception' in kwargs - exception = kwargs.pop('exception', None) +extra_python_paths = [ + Dir('src/python').srcnode().abspath, # M5 includes + Dir('ext/ply').srcnode().abspath, # ply is used by several files + ] - kwargs.setdefault('shell', False) - kwargs.setdefault('stdout', PIPE) - kwargs.setdefault('stderr', STDOUT) - kwargs.setdefault('close_fds', True) - try: - subp = Popen(cmd, **kwargs) - except Exception, e: - if no_exception: - return exception - raise - - return subp.communicate()[0] - -# helper function: compare arrays or strings of version numbers. -# E.g., compare_version((1,3,25), (1,4,1)') -# returns -1, 0, 1 if v1 is <, ==, > v2 -def compare_versions(v1, v2): - def make_version_list(v): - if isinstance(v, (list,tuple)): - return v - elif isinstance(v, str): - return map(lambda x: int(re.match('\d+', x).group()), v.split('.')) - else: - raise TypeError - - v1 = make_version_list(v1) - v2 = make_version_list(v2) - # Compare corresponding elements of lists - for n1,n2 in zip(v1, v2): - if n1 < n2: return -1 - if n1 > n2: return 1 - # all corresponding values are equal... see if one has extra values - if len(v1) < len(v2): return -1 - if len(v1) > len(v2): return 1 - return 0 +sys.path[1:1] = extra_python_paths + +from m5.util import compareVersions, readCommand ######################################################################## # @@ -162,7 +126,7 @@ def compare_versions(v1, v2): # ######################################################################## use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 'PATH', - 'RANLIB' ]) + 'PYTHONPATH', 'RANLIB' ]) use_env = {} for key,val in os.environ.iteritems(): @@ -173,6 +137,10 @@ main = Environment(ENV=use_env) main.root = Dir(".") # The current directory (where this file lives). main.srcdir = Dir("src") # The source directory +# add useful python code PYTHONPATH so it can be used by subprocesses +# as well +main.AppendENVPath('PYTHONPATH', extra_python_paths) + ######################################################################## # # Mercurial Stuff. @@ -217,7 +185,7 @@ if hgdir.exists(): # 1) Grab repository revision if we know it. cmd = "hg id -n -i -t -b" try: - hg_info = read_command(cmd, cwd=main.root.abspath).strip() + hg_info = readCommand(cmd, cwd=main.root.abspath).strip() except OSError: print mercurial_bin_not_found @@ -378,11 +346,8 @@ Export('extras_dir_list') # the ext directory should be on the #includes path main.Append(CPPPATH=[Dir('ext')]) -# M5_PLY is used by isa_parser.py to find the PLY package. -main.Append(ENV = { 'M5_PLY' : Dir('ext/ply').abspath }) - -CXX_version = read_command([main['CXX'],'--version'], exception=False) -CXX_V = read_command([main['CXX'],'-V'], exception=False) +CXX_version = readCommand([main['CXX'],'--version'], exception=False) +CXX_V = readCommand([main['CXX'],'-V'], exception=False) main['GCC'] = CXX_version and CXX_version.find('g++') >= 0 main['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0 @@ -426,7 +391,7 @@ if main['BATCH']: if sys.platform == 'cygwin': # cygwin has some header file issues... - main.Append(CCFLAGS=Split("-Wno-uninitialized")) + main.Append(CCFLAGS="-Wno-uninitialized") # Check for SWIG if not main.has_key('SWIG'): @@ -435,7 +400,7 @@ if not main.has_key('SWIG'): Exit(1) # Check for appropriate SWIG version -swig_version = read_command(('swig', '-version'), exception='').split() +swig_version = readCommand(('swig', '-version'), exception='').split() # First 3 words should be "SWIG Version x.y.z" if len(swig_version) < 3 or \ swig_version[0] != 'SWIG' or swig_version[1] != 'Version': @@ -443,7 +408,7 @@ if len(swig_version) < 3 or \ Exit(1) min_swig_version = '1.3.28' -if compare_versions(swig_version[2], min_swig_version) < 0: +if compareVersions(swig_version[2], min_swig_version) < 0: print 'Error: SWIG version', min_swig_version, 'or newer required.' print ' Installed version:', swig_version[2] Exit(1) @@ -514,8 +479,8 @@ conf.CheckLeading() try: import platform uname = platform.uname() - if uname[0] == 'Darwin' and compare_versions(uname[2], '9.0.0') >= 0: - if int(read_command('sysctl -n hw.cpu64bit_capable')[0]): + if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0: + if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]): main.Append(CCFLAGS='-arch x86_64') main.Append(CFLAGS='-arch x86_64') main.Append(LINKFLAGS='-arch x86_64') @@ -615,9 +580,9 @@ have_mysql = bool(mysql_config) # Check MySQL version. if have_mysql: - mysql_version = read_command(mysql_config + ' --version') + mysql_version = readCommand(mysql_config + ' --version') min_mysql_version = '4.1' - if compare_versions(mysql_version, min_mysql_version) < 0: + if compareVersions(mysql_version, min_mysql_version) < 0: print 'Warning: MySQL', min_mysql_version, 'or newer required.' print ' Version', mysql_version, 'detected.' have_mysql = False @@ -777,17 +742,10 @@ def make_switching_dir(dname, switch_headers, env): # list of ISAs from env['ALL_ISA_LIST']. def gen_switch_hdr(target, source, env): fname = str(target[0]) - bname = basename(fname) f = open(fname, 'w') - f.write('#include "arch/isa_specific.hh"\n') - cond = '#if' - for isa in all_isa_list: - f.write('%s THE_ISA == %s_ISA\n#include "%s/%s/%s"\n' - % (cond, isa.upper(), dname, isa, bname)) - cond = '#elif' - f.write('#else\n#error "THE_ISA not set"\n#endif\n') + isa = env['TARGET_ISA'].lower() + print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname)) f.close() - return 0 # String to print when generating header def gen_switch_hdr_string(target, source, env): diff --git a/build_opts/ARM_FS b/build_opts/ARM_FS new file mode 100644 index 000000000..508bad76e --- /dev/null +++ b/build_opts/ARM_FS @@ -0,0 +1,3 @@ +TARGET_ISA = 'arm' +CPU_MODELS = 'AtomicSimpleCPU,TimingSimpleCPU' +FULL_SYSTEM = 1 diff --git a/build_opts/POWER_SE b/build_opts/POWER_SE new file mode 100644 index 000000000..d76ca7180 --- /dev/null +++ b/build_opts/POWER_SE @@ -0,0 +1,3 @@ +TARGET_ISA = 'power' +FULL_SYSTEM = 0 +CPU_MODELS = 'AtomicSimpleCPU,TimingSimpleCPU,O3CPU' diff --git a/configs/common/Caches.py b/configs/common/Caches.py index 1c3b089c7..412cfd3b1 100644 --- a/configs/common/Caches.py +++ b/configs/common/Caches.py @@ -26,7 +26,6 @@ # # Authors: Lisa Hsu -import m5 from m5.objects import * class L1Cache(BaseCache): diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index 180e0ac52..7ab7319cd 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -26,8 +26,6 @@ # # Authors: Kevin Lim -import m5 -from m5 import makeList from m5.objects import * from Benchmarks import * @@ -81,6 +79,50 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None): return self +def makeLinuxAlphaRubySystem(mem_mode, rubymem, mdesc = None): + class BaseTsunami(Tsunami): + ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0) + ide = IdeController(disks=[Parent.disk0, Parent.disk2], + pci_func=0, pci_dev=0, pci_bus=0) + + + self = LinuxAlphaSystem(physmem = rubymem) + if not mdesc: + # generic system + mdesc = SysConfig() + self.readfile = mdesc.script() + + # Create pio bus to connect all device pio ports to rubymem's pio port + self.piobus = Bus(bus_id=0) + + self.disk0 = CowIdeDisk(driveID='master') + self.disk2 = CowIdeDisk(driveID='master') + self.disk0.childImage(mdesc.disk()) + self.disk2.childImage(disk('linux-bigswap2.img')) + self.tsunami = BaseTsunami() + self.tsunami.attachIO(self.piobus) + self.tsunami.ide.pio = self.piobus.port + self.tsunami.ethernet.pio = self.piobus.port + + # connect the dma ports directly to ruby dma ports + self.tsunami.ide.dma = self.physmem.dma_port + self.tsunami.ethernet.dma = self.physmem.dma_port + + # connect the pio bus to rubymem + self.physmem.pio_port = self.piobus.port + + self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(), + read_only = True)) + self.intrctrl = IntrControl() + self.mem_mode = mem_mode + self.terminal = Terminal() + self.kernel = binary('vmlinux') + self.pal = binary('ts_osfpal') + self.console = binary('console') + self.boot_osflags = 'root=/dev/hda1 console=ttyS0' + + return self + def makeSparcSystem(mem_mode, mdesc = None): class CowMmDisk(MmDisk): image = CowDiskImage(child=RawDiskImage(read_only=True), diff --git a/configs/common/Options.py b/configs/common/Options.py index 0ddd2f06d..abc26f1b5 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -38,6 +38,7 @@ parser.add_option("--fastmem", action="store_true") # Run duration options parser.add_option("-m", "--maxtick", type="int") parser.add_option("--maxtime", type="float") +parser.add_option("--maxinsts", type="int") parser.add_option("--prog_intvl", type="int") @@ -52,6 +53,9 @@ parser.add_option("--checkpoint-dir", action="store", type="string", help="Place all checkpoints in this absolute directory") parser.add_option("-r", "--checkpoint-restore", action="store", type="int", help="restore from checkpoint <N>") +parser.add_option("--checkpoint-at-end", action="store_true", + help="take a checkpoint at end of run") + # CPU Switching - default switch model goes from a checkpoint # to a timing simple CPU with caches to warm up, then to detailed CPU for @@ -61,6 +65,7 @@ parser.add_option("-s", "--standard-switch", action="store_true", parser.add_option("-w", "--warmup", action="store", type="int", help="if -s, then this is the warmup period. else, this is ignored", default=5000000000) +parser.add_option("--profile", help="CPU profile interval") # Fastforwarding and simpoint related materials parser.add_option("-W", "--warmup-insts", action="store", type="int", diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index d7dde241c..1c9d4ff4e 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -28,9 +28,13 @@ from os import getcwd from os.path import join as joinpath + import m5 +from m5.defines import buildEnv from m5.objects import * -m5.AddToPath('../common') +from m5.util import * + +addToPath('../common') def setCPUClass(options): @@ -82,10 +86,10 @@ def run(options, root, testsys, cpu_class): cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: - m5.fatal("Error: Can't specify both --fast-forward and --checkpoint-restore") + fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: - m5.fatal("Error: Must specify --caches when using --standard-switch") + fatal("Must specify --caches when using --standard-switch") np = options.num_cpus max_checkpoints = options.max_checkpoints @@ -95,6 +99,10 @@ def run(options, root, testsys, cpu_class): for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_intvl + if options.maxinsts: + for i in xrange(np): + testsys.cpu[i].max_insts_any_thread = options.maxinsts + if cpu_class: switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i)) for i in xrange(np)] @@ -103,7 +111,7 @@ def run(options, root, testsys, cpu_class): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys - if not m5.build_env['FULL_SYSTEM']: + if not buildEnv['FULL_SYSTEM']: switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[0].clock # simulation period @@ -122,7 +130,7 @@ def run(options, root, testsys, cpu_class): for i in xrange(np): switch_cpus[i].system = testsys switch_cpus_1[i].system = testsys - if not m5.build_env['FULL_SYSTEM']: + if not buildEnv['FULL_SYSTEM']: switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[0].clock @@ -137,7 +145,7 @@ def run(options, root, testsys, cpu_class): # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: - m5.fatal('simpoint not found') + fatal('simpoint not found') testsys.cpu[i].max_insts_any_thread = \ testsys.cpu[i].workload[0].simpoint # No distance specified, just switch @@ -170,7 +178,7 @@ def run(options, root, testsys, cpu_class): if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: - m5.fatal('no simpoint for testsys.cpu[%d].workload[0]', i) + fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below @@ -190,14 +198,13 @@ def run(options, root, testsys, cpu_class): import re if not isdir(cptdir): - m5.fatal("checkpoint dir %s does not exist!", cptdir) + fatal("checkpoint dir %s does not exist!", cptdir) if options.at_instruction: checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % \ (options.bench, options.checkpoint_restore)) if not exists(checkpoint_dir): - m5.fatal("Unable to find checkpoint directory %s", - checkpoint_dir) + fatal("Unable to find checkpoint directory %s", checkpoint_dir) print "Restoring checkpoint ..." m5.restoreCheckpoint(root, checkpoint_dir) @@ -205,7 +212,7 @@ def run(options, root, testsys, cpu_class): elif options.simpoint: # assume workload 0 has the simpoint if testsys.cpu[0].workload[0].simpoint == 0: - m5.fatal('Unable to find simpoint') + fatal('Unable to find simpoint') options.checkpoint_restore += \ int(testsys.cpu[0].workload[0].simpoint) @@ -213,8 +220,8 @@ def run(options, root, testsys, cpu_class): checkpoint_dir = joinpath(cptdir, "cpt.%s.%d" % \ (options.bench, options.checkpoint_restore)) if not exists(checkpoint_dir): - m5.fatal("Unable to find checkpoint directory %s.%s", - options.bench, options.checkpoint_restore) + fatal("Unable to find checkpoint directory %s.%s", + options.bench, options.checkpoint_restore) print "Restoring checkpoint ..." m5.restoreCheckpoint(root,checkpoint_dir) @@ -233,7 +240,7 @@ def run(options, root, testsys, cpu_class): cpt_num = options.checkpoint_restore if cpt_num > len(cpts): - m5.fatal('Checkpoint %d not found', cpt_num) + fatal('Checkpoint %d not found', cpt_num) ## Adjust max tick based on our starting tick maxtick = maxtick - int(cpts[cpt_num - 1]) @@ -367,3 +374,6 @@ def run(options, root, testsys, cpu_class): exit_cause = exit_event.getCause() print 'Exiting @ cycle %i because %s' % (m5.curTick(), exit_cause) + if options.checkpoint_at_end: + m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) + diff --git a/configs/example/fs.py b/configs/example/fs.py index b5be79a08..23285e101 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -26,15 +26,20 @@ # # Authors: Ali Saidi -import optparse, os, sys +import optparse +import os +import sys import m5 +from m5.defines import buildEnv +from m5.objects import * +from m5.util import addToPath, fatal -if not m5.build_env['FULL_SYSTEM']: - m5.fatal("This script requires full-system mode (*_FS).") +if not buildEnv['FULL_SYSTEM']: + fatal("This script requires full-system mode (*_FS).") + +addToPath('../common') -from m5.objects import * -m5.AddToPath('../common') from FSConfig import * from SysPaths import * from Benchmarks import * @@ -98,16 +103,16 @@ else: np = options.num_cpus -if m5.build_env['TARGET_ISA'] == "alpha": +if buildEnv['TARGET_ISA'] == "alpha": test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0]) -elif m5.build_env['TARGET_ISA'] == "mips": +elif buildEnv['TARGET_ISA'] == "mips": test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0]) -elif m5.build_env['TARGET_ISA'] == "sparc": +elif buildEnv['TARGET_ISA'] == "sparc": test_sys = makeSparcSystem(test_mem_mode, bm[0]) -elif m5.build_env['TARGET_ISA'] == "x86": +elif buildEnv['TARGET_ISA'] == "x86": test_sys = makeLinuxX86System(test_mem_mode, np, bm[0]) else: - m5.fatal("incapable of building non-alpha or non-sparc full system!") + fatal("incapable of building non-alpha or non-sparc full system!") if options.kernel is not None: test_sys.kernel = binary(options.kernel) @@ -123,7 +128,7 @@ if options.l2cache: test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)] -if options.caches: +if options.caches or options.l2cache: test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max)] test_sys.bridge.filter_ranges_b=[AddrRange(0, size='8GB')] test_sys.iocache = IOCache(addr_range=AddrRange(0, size='8GB')) @@ -142,17 +147,17 @@ for i in xrange(np): if options.fastmem: test_sys.cpu[i].physmem_port = test_sys.physmem.port -if m5.build_env['TARGET_ISA'] == 'mips': +if buildEnv['TARGET_ISA'] == 'mips': setMipsOptions(TestCPUClass) if len(bm) == 2: - if m5.build_env['TARGET_ISA'] == 'alpha': + if buildEnv['TARGET_ISA'] == 'alpha': drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1]) - elif m5.build_env['TARGET_ISA'] == 'mips': + elif buildEnv['TARGET_ISA'] == 'mips': drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1]) - elif m5.build_env['TARGET_ISA'] == 'sparc': + elif buildEnv['TARGET_ISA'] == 'sparc': drive_sys = makeSparcSystem(drive_mem_mode, bm[1]) - elif m5.build.env['TARGET_ISA'] == 'x86': + elif buildEnv['TARGET_ISA'] == 'x86': drive_sys = makeX86System(drive_mem_mode, np, bm[1]) drive_sys.cpu = DriveCPUClass(cpu_id=0) drive_sys.cpu.connectMemPorts(drive_sys.membus) diff --git a/configs/example/memtest-ruby.py b/configs/example/memtest-ruby.py new file mode 100644 index 000000000..e47b8e0a3 --- /dev/null +++ b/configs/example/memtest-ruby.py @@ -0,0 +1,122 @@ +# Copyright (c) 2006-2007 The Regents of The University of Michigan +# Copyright (c) 2009 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ron Dreslinski +# Brad Beckmann + +import m5 +from m5.objects import * +from m5.defines import buildEnv +from m5.util import addToPath +import os, optparse, sys +addToPath('../common') +addToPath('../../tests/configs/') +import ruby_config + +parser = optparse.OptionParser() + +parser.add_option("-a", "--atomic", action="store_true", + help="Use atomic (non-timing) mode") +parser.add_option("-b", "--blocking", action="store_true", + help="Use blocking caches") +parser.add_option("-l", "--maxloads", metavar="N", default=0, + help="Stop after N loads") +parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick, + metavar="T", + help="Stop after T ticks") + +parser.add_option("-t", "--testers", type="int", metavar="N", default=1, + help="number of testers/cores") + +parser.add_option("-f", "--functional", type="int", default=0, + metavar="PCT", + help="Target percentage of functional accesses " + "[default: %default]") +parser.add_option("-u", "--uncacheable", type="int", default=0, + metavar="PCT", + help="Target percentage of uncacheable accesses " + "[default: %default]") + +parser.add_option("--progress", type="int", default=1000, + metavar="NLOADS", + help="Progress message interval " + "[default: %default]") + +(options, args) = parser.parse_args() + +if args: + print "Error: script doesn't take any positional arguments" + sys.exit(1) + +block_size = 64 + +if options.testers > block_size: + print "Error: Number of testers %d limited to %d because of false sharing" \ + % (options.testers, block_size) + sys.exit(1) + +cpus = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, \ + percent_functional=options.functional, \ + percent_uncacheable=options.uncacheable, \ + progress_interval=options.progress) \ + for i in xrange(options.testers) ] + +# create the desired simulated system +# ruby memory must be at least 16 MB to work with the mem tester +ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", + cores = options.testers, + memory_size = 16, + ports_per_cpu = 1) + +system = System(cpu = cpus, funcmem = PhysicalMemory(), + physmem = ruby_memory) + +for cpu in cpus: + cpu.test = system.physmem.port + cpu.functional = system.funcmem.port + + +# ----------------------- +# run simulation +# ----------------------- + +root = Root( system = system ) +if options.atomic: + root.system.mem_mode = 'atomic' +else: + root.system.mem_mode = 'timing' + +# Not much point in this being higher than the L1 latency +m5.ticks.setGlobalFrequency('1ns') + +# instantiate configuration +m5.instantiate(root) + +# simulate until program terminates +exit_event = m5.simulate(options.maxtick) + +print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause() diff --git a/configs/example/memtest.py b/configs/example/memtest.py index 5bb874e85..d4497092b 100644 --- a/configs/example/memtest.py +++ b/configs/example/memtest.py @@ -26,10 +26,11 @@ # # Authors: Ron Dreslinski +import optparse +import sys + import m5 from m5.objects import * -import os, optparse, sys -m5.AddToPath('../common') parser = optparse.OptionParser() diff --git a/configs/example/ruby_fs.py b/configs/example/ruby_fs.py new file mode 100644 index 000000000..a4831f3bb --- /dev/null +++ b/configs/example/ruby_fs.py @@ -0,0 +1,201 @@ +# Copyright (c) 2009 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Brad Beckmann + +# +# Full system configuraiton for ruby +# + +import os +import optparse +import sys +from os.path import join as joinpath + +import m5 +from m5.defines import buildEnv +from m5.objects import * +from m5.util import addToPath, panic + +if not buildEnv['FULL_SYSTEM']: + panic("This script requires full-system mode (*_FS).") + +addToPath('../../tests/configs/') +addToPath('../common') + +import ruby_config + +from FSConfig import * +from SysPaths import * +from Benchmarks import * +import Simulation +from Caches import * + +# Get paths we might need. It's expected this file is in m5/configs/example. +config_path = os.path.dirname(os.path.abspath(__file__)) +config_root = os.path.dirname(config_path) +m5_root = os.path.dirname(config_root) + +parser = optparse.OptionParser() + +# Benchmark options +parser.add_option("-b", "--benchmark", action="store", type="string", + dest="benchmark", + help="Specify the benchmark to run. Available benchmarks: %s"\ + % DefinedBenchmarks) +parser.add_option("-o", "--options", default="", + help='The options to pass to the binary, use " " around the entire string') +parser.add_option("-i", "--input", default="", help="Read stdin from a file.") +parser.add_option("--output", default="", help="Redirect stdout to a file.") +parser.add_option("--errout", default="", help="Redirect stderr to a file.") + +# ruby options +parser.add_option("--ruby-debug", action="store_true") +parser.add_option("--ruby-debug-file", default="", help="Ruby debug out file (stdout if blank)") +parser.add_option("--protocol", default="", help="Ruby protocol compiled into binary") + + +# ruby host memory experimentation +parser.add_option("--cache_size", type="int") +parser.add_option("--cache_assoc", type="int") +parser.add_option("--map_levels", type="int") + +execfile(os.path.join(config_root, "common", "Options.py")) + +(options, args) = parser.parse_args() + +if args: + print "Error: script doesn't take any positional arguments" + sys.exit(1) + +if options.benchmark: + try: + bm = Benchmarks[options.benchmark] + except KeyError: + print "Error benchmark %s has not been defined." % options.benchmark + print "Valid benchmarks are: %s" % DefinedBenchmarks + sys.exit(1) +else: + bm = [SysConfig()] + +# +# currently ruby fs only works in simple timing mode because ruby does not +# support atomic accesses by devices. Also ruby_fs currently assumes +# that is running a checkpoints that were created by ALPHA_FS under atomic +# mode. Since switch cpus are not defined in these checkpoints, we don't +# fast forward with the atomic cpu and instead set the FutureClass to None. +# Therefore the cpus resolve to the correct names and unserialize correctly. +# +assert(options.timing) +class CPUClass(TimingSimpleCPU): pass +test_mem_mode = 'timing' +FutureClass = None + +CPUClass.clock = '1GHz' + +# +# Since we are running in timing mode, set the number of M5 ticks to ruby ticks +# to the cpu clock frequency +# +M5_to_ruby_tick = '1000t' + +np = options.num_cpus + +# check for max instruction count +if options.max_inst: + max_inst = options.max_inst +else: + max_inst = 0 + +# set cache size +if options.cache_size: + cache_size = options.cache_size +else: + cache_size = 32768 # 32 kB is default + +# set cache assoc +if options.cache_assoc: + cache_assoc = options.cache_assoc +else: + cache_assoc = 8 # 8 is default + +# set map levels +if options.map_levels: + map_levels = options.map_levels +else: + map_levels = 4 # 4 levels is the default + +if options.protocol == "MOESI_hammer": + ruby_config_file = "MOESI_hammer-homogeneous.rb" +elif options.protocol == "MOESI_CMP_token": + ruby_config_file = "TwoLevel_SplitL1UnifiedL2.rb" +elif options.protocol == "MI_example": + ruby_config_file = "MI_example-homogeneous.rb" +else: + print "Error: unsupported ruby protocol" + sys.exit(1) + +# +# Currently, since ruby configuraiton is separate from m5, we need to manually +# tell ruby that two dma ports are created by makeLinuxAlphaRubySystem(). +# Eventually, this will be fix with a unified configuration system. +# +rubymem = ruby_config.generate(ruby_config_file, + np, + np, + 128, + False, + cache_size, + cache_assoc, + map_levels, + 2, + M5_to_ruby_tick) + +if options.ruby_debug == True: + rubymem.debug = True + rubymem.debug_file = options.ruby_debug_file + +system = makeLinuxAlphaRubySystem(test_mem_mode, rubymem, bm[0]) + +system.cpu = [CPUClass(cpu_id=i) for i in xrange(np)] + +if options.l2cache: + print "Error: -l2cache incompatible with ruby, must configure it ruby-style" + sys.exit(1) + +if options.caches: + print "Error: -caches incompatible with ruby, must configure it ruby-style" + sys.exit(1) + +for i in xrange(np): + system.cpu[i].connectMemPorts(system.physmem) + + if options.fastmem: + system.cpu[i].physmem_port = system.physmem.port + +root = Root(system = system) + +Simulation.run(options, root, system, FutureClass) diff --git a/configs/example/ruby_se.py b/configs/example/ruby_se.py index 488ccb64a..e7e930077 100644 --- a/configs/example/ruby_se.py +++ b/configs/example/ruby_se.py @@ -30,17 +30,22 @@ # # "m5 test.py" +import os +import optparse +import sys +from os.path import join as joinpath + import m5 +from m5.defines import buildEnv +from m5.objects import * +from m5.util import addToPath, panic -if m5.build_env['FULL_SYSTEM']: - m5.panic("This script requires syscall emulation mode (*_SE).") +if buildEnv['FULL_SYSTEM']: + panic("This script requires syscall emulation mode (*_SE).") + +addToPath('../common') -from m5.objects import * -import os, optparse, sys -from os.path import join as joinpath -m5.AddToPath('../common') import Simulation -#from Caches import * from cpu2000 import * # Get paths we might need. It's expected this file is in m5/configs/example. @@ -72,7 +77,7 @@ if args: if options.bench: try: - if m5.build_env['TARGET_ISA'] != 'alpha': + if buildEnv['TARGET_ISA'] != 'alpha': print >>sys.stderr, "Simpoints code only works for Alpha ISA at this time" sys.exit(1) exec("workload = %s('alpha', 'tru64', 'ref')" % options.bench) @@ -133,7 +138,6 @@ rubymem = RubyMemory( range = AddrRange("512MB"), clock = "1GHz", num_cpus = np, - libruby_file = "src/mem/ruby/amd64-linux/generated/MOESI_CMP_directory/bin/libruby.so", config_file = "ruby.config", stats_file = "m5out/ruby.stats" ) diff --git a/configs/example/se.py b/configs/example/se.py index 67a2340ce..c490ed6b6 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -30,15 +30,21 @@ # # "m5 test.py" +import os +import optparse +import sys +from os.path import join as joinpath + import m5 +from m5.defines import buildEnv +from m5.objects import * +from m5.util import addToPath, fatal -if m5.build_env['FULL_SYSTEM']: - m5.fatal("This script requires syscall emulation mode (*_SE).") +if buildEnv['FULL_SYSTEM']: + fatal("This script requires syscall emulation mode (*_SE).") + +addToPath('../common') -from m5.objects import * -import os, optparse, sys -from os.path import join as joinpath -m5.AddToPath('../common') import Simulation from Caches import * from cpu2000 import * @@ -70,7 +76,7 @@ if args: if options.bench: try: - if m5.build_env['TARGET_ISA'] != 'alpha': + if buildEnv['TARGET_ISA'] != 'alpha': print >>sys.stderr, "Simpoints code only works for Alpha ISA at this time" sys.exit(1) exec("workload = %s('alpha', 'tru64', 'ref')" % options.bench) @@ -94,8 +100,9 @@ if options.errout != "": # By default, set workload to path of user-specified binary workloads = options.cmd +numThreads = 1 -if options.detailed: +if options.detailed or options.inorder: #check for SMT workload workloads = options.cmd.split(';') if len(workloads) > 1: @@ -124,11 +131,12 @@ if options.detailed: smt_process.errout = errouts[smt_idx] process += [smt_process, ] smt_idx += 1 - + numThreads = len(workloads) + (CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) CPUClass.clock = '2GHz' -CPUClass.numThreads = len(workloads) +CPUClass.numThreads = numThreads; np = options.num_cpus diff --git a/configs/splash2/cluster.py b/configs/splash2/cluster.py index 769bdcf5a..45c9ede82 100644 --- a/configs/splash2/cluster.py +++ b/configs/splash2/cluster.py @@ -30,10 +30,14 @@ # # "m5 test.py" +import os +import optparse +import sys + import m5 from m5.objects import * -import os, optparse, sys -m5.AddToPath('../common') + +m5.util.addToPath('../common') # -------------------- # Define Command Line Options @@ -266,10 +270,11 @@ elif options.benchmark == 'WaterNSquared': elif options.benchmark == 'WaterSpatial': root.workload = Water_spatial() else: - panic("The --benchmark environment variable was set to something" \ - +" improper.\nUse Cholesky, FFT, LUContig, LUNoncontig, Radix" \ - +", Barnes, FMM, OceanContig,\nOceanNoncontig, Raytrace," \ - +" WaterNSquared, or WaterSpatial\n") + m5.util.panic(""" +The --benchmark environment variable was set to something improper. +Use Cholesky, FFT, LUContig, LUNoncontig, Radix, Barnes, FMM, OceanContig, +OceanNoncontig, Raytrace, WaterNSquared, or WaterSpatial +""") # -------------------- # Assign the workload to the cpus diff --git a/configs/splash2/run.py b/configs/splash2/run.py index afa85a8f1..95ec790ba 100644 --- a/configs/splash2/run.py +++ b/configs/splash2/run.py @@ -29,10 +29,14 @@ # Splash2 Run Script # +import os +import optparse +import sys + import m5 from m5.objects import * -import os, optparse, sys -m5.AddToPath('../common') + +m5.util.addToPath('../common') # -------------------- # Define Command Line Options diff --git a/src/SConscript b/src/SConscript index d96922b49..d02d2a6e7 100644 --- a/src/SConscript +++ b/src/SConscript @@ -49,7 +49,7 @@ Import('*') # Children need to see the environment Export('env') -build_env = dict([(opt, env[opt]) for opt in export_vars]) +build_env = [(opt, env[opt]) for opt in export_vars] ######################################################################## # Code for adding source files of various types @@ -132,15 +132,15 @@ class PySource(SourceFile): modpath = '.'.join(modpath) arcpath = path + [ self.basename ] - debugname = self.snode.abspath - if not exists(debugname): - debugname = self.tnode.abspath + abspath = self.snode.abspath + if not exists(abspath): + abspath = self.tnode.abspath self.package = package self.modname = modname self.modpath = modpath self.arcname = joinpath(*arcpath) - self.debugname = debugname + self.abspath = abspath self.compiled = File(self.filename + 'c') self.assembly = File(self.filename + '.s') self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath) @@ -228,9 +228,6 @@ env.Append(CPPPATH=Dir('.')) for extra_dir in extras_dir_list: env.Append(CPPPATH=Dir(extra_dir)) -# Add a flag defining what THE_ISA should be for all compilation -env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) - # Workaround for bug in SCons version > 0.97d20071212 # Scons bug id: 2006 M5 Bug id: 308 for root, dirs, files in os.walk(base_dir, topdown=True): @@ -261,11 +258,38 @@ for extra_dir in extras_dir_list: for opt in export_vars: env.ConfigFile(opt) +def makeTheISA(source, target, env): + f = file(str(target[0]), 'w') + + isas = [ src.get_contents() for src in source ] + target = env['TARGET_ISA'] + def define(isa): + return isa.upper() + '_ISA' + + def namespace(isa): + return isa[0].upper() + isa[1:].lower() + 'ISA' + + + print >>f, '#ifndef __CONFIG_THE_ISA_HH__' + print >>f, '#define __CONFIG_THE_ISA_HH__' + print >>f + for i,isa in enumerate(isas): + print >>f, '#define %s %d' % (define(isa), i + 1) + print >>f + print >>f, '#define THE_ISA %s' % (define(target)) + print >>f, '#define TheISA %s' % (namespace(target)) + print >>f + print >>f, '#endif // __CONFIG_THE_ISA_HH__' + +env.Command('config/the_isa.hh', map(Value, all_isa_list), makeTheISA) + ######################################################################## # # Prevent any SimObjects from being added after this point, they # should all have been added in the SConscripts above # +SimObject.fixed = True + class DictImporter(object): '''This importer takes a dictionary of arbitrary module names that map to arbitrary filenames.''' @@ -283,7 +307,7 @@ class DictImporter(object): self.installed = set() def find_module(self, fullname, path): - if fullname == 'defines': + if fullname == 'm5.defines': return self if fullname == 'm5.objects': @@ -293,7 +317,7 @@ class DictImporter(object): return None source = self.modules.get(fullname, None) - if source is not None and exists(source.snode.abspath): + if source is not None and fullname.startswith('m5.objects'): return self return None @@ -308,28 +332,31 @@ class DictImporter(object): mod.__path__ = fullname.split('.') return mod - if fullname == 'defines': - mod.__dict__['buildEnv'] = build_env + if fullname == 'm5.defines': + mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) return mod source = self.modules[fullname] if source.modname == '__init__': mod.__path__ = source.modpath - mod.__file__ = source.snode.abspath + mod.__file__ = source.abspath - exec file(source.snode.abspath, 'r') in mod.__dict__ + exec file(source.abspath, 'r') in mod.__dict__ return mod +import m5.SimObject +import m5.params + +m5.SimObject.clear() +m5.params.clear() + # install the python importer so we can grab stuff from the source # tree itself. We can't have SimObjects added after this point or # else we won't know about them for the rest of the stuff. -SimObject.fixed = True importer = DictImporter(PySource.modules) sys.meta_path[0:0] = [ importer ] -import m5 - # import all sim objects so we can populate the all_objects list # make sure that we're working with a list, then let's sort it for modname in SimObject.modnames: @@ -346,6 +373,12 @@ all_enums = m5.params.allEnums all_params = {} for name,obj in sorted(sim_objects.iteritems()): for param in obj._params.local.values(): + # load the ptype attribute now because it depends on the + # current version of SimObject.allClasses, but when scons + # actually uses the value, all versions of + # SimObject.allClasses will have been loaded + param.ptype + if not hasattr(param, 'swig_decl'): continue pname = param.ptype_str @@ -365,13 +398,27 @@ depends = [ PySource.modules[dep].tnode for dep in module_depends ] # # Generate Python file containing a dict specifying the current -# build_env flags. +# buildEnv flags. def makeDefinesPyFile(target, source, env): - f = file(str(target[0]), 'w') build_env, hg_info = [ x.get_contents() for x in source ] - print >>f, "buildEnv = %s" % build_env - print >>f, "hgRev = '%s'" % hg_info - f.close() + + code = m5.util.code_formatter() + code(""" +import m5.internal +import m5.util + +buildEnv = m5.util.SmartDict($build_env) +hgRev = '$hg_info' + +compileDate = m5.internal.core.compileDate +_globals = globals() +for key,val in m5.internal.core.__dict__.iteritems(): + if key.startswith('flag_'): + flag = key[5:] + _globals[flag] = val +del _globals +""") + code.write(str(target[0])) defines_info = [ Value(build_env), Value(env['HG_INFO']) ] # Generate a file with all of the compile options in it @@ -467,12 +514,7 @@ for name,simobj in sorted(sim_objects.iteritems()): # Generate any parameter header files needed params_i_files = [] for name,param in all_params.iteritems(): - if isinstance(param, m5.params.VectorParamDesc): - ext = 'vptype' - else: - ext = 'ptype' - - i_file = File('params/%s_%s.i' % (name, ext)) + i_file = File('params/%s_%s.i' % (name, param.file_ext)) params_i_files.append(i_file) env.Command(i_file, Value(name), createSwigParam) env.Depends(i_file, depends) @@ -850,7 +892,7 @@ def objectifyPyFile(target, source, env): dst = file(str(target[0]), 'w') pysource = PySource.tnodes[source[0]] - compiled = compile(src, pysource.debugname, 'exec') + compiled = compile(src, pysource.abspath, 'exec') marshalled = marshal.dumps(compiled) compressed = zlib.compress(marshalled) data = compressed diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index e93e16711..ff6de8d03 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -144,7 +144,7 @@ DtbFault::invoke(ThreadContext *tc) // read, like the EV5). The EV6 approach is cleaner and seems to // work with EV5 PAL code, but not the other way around. if (!tc->misspeculating() && - reqFlags.noneSet(Request::VPTE|Request::NO_FAULT)) { + reqFlags.noneSet(Request::VPTE | Request::PREFETCH)) { // set VA register with faulting address tc->setMiscRegNoEffect(IPR_VA, vaddr); diff --git a/src/arch/alpha/isa.cc b/src/arch/alpha/isa.cc index eee391a0d..8b6da3649 100644 --- a/src/arch/alpha/isa.cc +++ b/src/arch/alpha/isa.cc @@ -36,7 +36,7 @@ namespace AlphaISA { void -ISA::serialize(std::ostream &os) +ISA::serialize(EventManager *em, std::ostream &os) { SERIALIZE_SCALAR(fpcr); SERIALIZE_SCALAR(uniq); @@ -46,7 +46,7 @@ ISA::serialize(std::ostream &os) } void -ISA::unserialize(Checkpoint *cp, const std::string §ion) +ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string §ion) { UNSERIALIZE_SCALAR(fpcr); UNSERIALIZE_SCALAR(uniq); diff --git a/src/arch/alpha/isa.hh b/src/arch/alpha/isa.hh index 622d1da4c..574b50841 100644 --- a/src/arch/alpha/isa.hh +++ b/src/arch/alpha/isa.hh @@ -83,8 +83,9 @@ namespace AlphaISA intr_flag = 0; } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion); void reset(std::string core_name, ThreadID num_threads, unsigned num_vpes, BaseCPU *_cpu) diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index cb43fcb74..52e124ad5 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -627,7 +627,7 @@ decode OPCODE default Unknown::unknown() { format MiscPrefetch { 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, {{ xc->writeHint(EA, 64, memAccessFlags); }}, - mem_flags = NO_FAULT, + mem_flags = PREFETCH, inst_flags = [IsMemRef, IsDataPrefetch, IsStore, MemWriteOp]); } diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa index fedfbf55d..b1703221f 100644 --- a/src/arch/alpha/isa/mem.isa +++ b/src/arch/alpha/isa/mem.isa @@ -548,7 +548,7 @@ def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, pf_flags = makeList(pf_flags) inst_flags = makeList(inst_flags) - pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_mem_flags = mem_flags + pf_flags + ['PREFETCH'] pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp'] diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index c622c5ef1..c728ce1fb 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -105,6 +105,7 @@ class AlphaLinux : public Linux static const unsigned TIOCISATTY_ = 0x2000745e; static const unsigned TIOCGETS_ = 0x402c7413; static const unsigned TIOCGETA_ = 0x40127417; + static const unsigned TCSETAW_ = 0x80147419; // 2.6.15 kernel //@} /// For table(). @@ -125,6 +126,21 @@ class AlphaLinux : public Linux TGT_RLIMIT_MEMLOCK = 9, TGT_RLIMIT_LOCKS = 10 }; + + typedef struct { + int64_t uptime; /* Seconds since boot */ + uint64_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t sharedram; /* Amount of shared memory */ + uint64_t bufferram; /* Memory used by buffers */ + uint64_t totalswap; /* Total swap space size */ + uint64_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint64_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; }; #endif // __ALPHA_ALPHA_LINUX_LINUX_HH__ diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 9886c7ea7..a653d7845 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -48,7 +48,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -67,13 +68,15 @@ static SyscallReturn osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg<uint64_t> fpcr(bufPtr); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -94,13 +97,15 @@ static SyscallReturn osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg<uint64_t> fpcr(bufPtr); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " @@ -440,7 +445,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 315 */ SyscallDesc("munlock", unimplementedFunc), /* 316 */ SyscallDesc("mlockall", unimplementedFunc), /* 317 */ SyscallDesc("munlockall", unimplementedFunc), - /* 318 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 318 */ SyscallDesc("sysinfo", sysinfoFunc<AlphaLinux>), /* 319 */ SyscallDesc("_sysctl", unimplementedFunc), /* 320 */ SyscallDesc("was sys_idle", unimplementedFunc), /* 321 */ SyscallDesc("oldumount", unimplementedFunc), diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 6aad45da8..9d75d5fa1 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -193,10 +193,10 @@ AlphaLiveProcess::startup() } AlphaISA::IntReg -AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i) +AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return tc->readIntReg(FirstArgumentReg + i); + return tc->readIntReg(FirstArgumentReg + i++); } void diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index 6d083c5ac..36b25a48e 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -44,7 +44,7 @@ class AlphaLiveProcess : public LiveProcess void argsInit(int intSize, int pageSize); public: - AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i); + AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 8fa3cdeda..b039fbe19 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -45,7 +45,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "OSF1"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -62,35 +63,36 @@ static SyscallReturn getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); - unsigned nbytes = process->getSyscallArg(tc, 2); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); + unsigned nbytes = process->getSyscallArg(tc, index); switch (op) { case AlphaTru64::GSI_MAX_CPU: { - TypedBufferArg<uint32_t> max_cpu(process->getSyscallArg(tc, 1)); + TypedBufferArg<uint32_t> max_cpu(bufPtr); *max_cpu = htog((uint32_t)process->numCpus()); max_cpu.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPUS_IN_BOX: { - TypedBufferArg<uint32_t> cpus_in_box(process->getSyscallArg(tc, 1)); + TypedBufferArg<uint32_t> cpus_in_box(bufPtr); *cpus_in_box = htog((uint32_t)process->numCpus()); cpus_in_box.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PHYSMEM: { - TypedBufferArg<uint64_t> physmem(process->getSyscallArg(tc, 1)); + TypedBufferArg<uint64_t> physmem(bufPtr); *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPU_INFO: { - TypedBufferArg<AlphaTru64::cpu_info> - infop(process->getSyscallArg(tc, 1)); + TypedBufferArg<AlphaTru64::cpu_info> infop(bufPtr); infop->current_cpu = htog(0); infop->cpus_in_box = htog(process->numCpus()); @@ -107,14 +109,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_PROC_TYPE: { - TypedBufferArg<uint64_t> proc_type(process->getSyscallArg(tc, 1)); + TypedBufferArg<uint64_t> proc_type(bufPtr); *proc_type = htog((uint64_t)11); proc_type.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PLATFORM_NAME: { - BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes); + BufferArg bufArg(bufPtr, nbytes); strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); @@ -123,7 +125,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_CLK_TCK: { - TypedBufferArg<uint64_t> clk_hz(process->getSyscallArg(tc, 1)); + TypedBufferArg<uint64_t> clk_hz(bufPtr); *clk_hz = htog((uint64_t)1024); clk_hz.copyOut(tc->getMemPort()); return 1; @@ -142,12 +144,13 @@ static SyscallReturn setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); switch (op) { case AlphaTru64::SSI_IEEE_FP_CONTROL: warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", - process->getSyscallArg(tc, 1)); + process->getSyscallArg(tc, index)); break; default: @@ -165,17 +168,19 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { using namespace std; - int id = process->getSyscallArg(tc, 0); // table ID - int index = process->getSyscallArg(tc, 1); // index into table + int argIndex = 0; + int id = process->getSyscallArg(tc, argIndex); // table ID + int index = process->getSyscallArg(tc, argIndex); // index into table + Addr bufPtr = process->getSyscallArg(tc, argIndex); // arg 2 is buffer pointer; type depends on table ID - int nel = process->getSyscallArg(tc, 3); // number of elements - int lel = process->getSyscallArg(tc, 4); // expected element size + int nel = process->getSyscallArg(tc, argIndex); // number of elements + int lel = process->getSyscallArg(tc, argIndex); // expected element size switch (id) { case AlphaTru64::TBL_SYSINFO: { if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) return -EINVAL; - TypedBufferArg<Tru64::tbl_sysinfo> elp(process->getSyscallArg(tc, 2)); + TypedBufferArg<Tru64::tbl_sysinfo> elp(bufPtr); const int clk_hz = one_million; elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh index 4ba35fc50..0ee12973c 100644 --- a/src/arch/alpha/tru64/tru64.hh +++ b/src/arch/alpha/tru64/tru64.hh @@ -99,6 +99,7 @@ class AlphaTru64 : public Tru64 static const unsigned TIOCISATTY_ = 0x2000745e; static const unsigned TIOCGETS_ = 0x402c7413; static const unsigned TIOCGETA_ = 0x40127417; + static const unsigned TCSETAW_ = 0x80147419; //@} //@{ diff --git a/src/arch/arm/ArmInterrupts.py b/src/arch/arm/ArmInterrupts.py new file mode 100644 index 000000000..f21d49e95 --- /dev/null +++ b/src/arch/arm/ArmInterrupts.py @@ -0,0 +1,33 @@ +# Copyright (c) 2009 ARM Limited +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ali Saidi + +from m5.SimObject import SimObject + +class ArmInterrupts(SimObject): + type = 'ArmInterrupts' + cxx_class = 'ArmISA::Interrupts' diff --git a/src/python/m5/environment.py b/src/arch/arm/ArmSystem.py index bea0bc1d0..872776c69 100644 --- a/src/python/m5/environment.py +++ b/src/arch/arm/ArmSystem.py @@ -1,4 +1,4 @@ -# Copyright (c) 2005 The Regents of The University of Michigan +# Copyright (c) 2009 ARM Limited # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -24,20 +24,12 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# Authors: Nathan Binkert -# Steve Reinhardt +# Authors: Ali Saidi -import os +from m5.params import * -# import the m5 compile options -import defines +from System import System -# make a SmartDict out of the build options for our local use -import smartdict -build_env = smartdict.SmartDict() -build_env.update(defines.m5_build_env) - -# make a SmartDict out of the OS environment too -env = smartdict.SmartDict() -env.update(os.environ) +class ArmSystem(System): + type = 'ArmSystem' diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index 55ecabdc3..92a4193f1 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -1,6 +1,7 @@ # -*- mode:python -*- # Copyright (c) 2007-2008 The Florida State University +# Copyright (c) 2009 ARM Limited # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,6 +28,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Stephen Hines +# Ali Saidi Import('*') @@ -43,15 +45,20 @@ if env['TARGET_ISA'] == 'arm': Source('pagetable.cc') Source('tlb.cc') Source('vtophys.cc') + Source('utility.cc') SimObject('ArmNativeTrace.py') SimObject('ArmTLB.py') TraceFlag('Arm') - + TraceFlag('Faults', "Trace Exceptions, interrupts, svc/swi") if env['FULL_SYSTEM']: - #Insert Full-System Files Here - pass + Source('interrupts.cc') + Source('stacktrace.cc') + Source('system.cc') + + SimObject('ArmInterrupts.py') + SimObject('ArmSystem.py') else: Source('process.cc') Source('linux/linux.cc') diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 3d882c97f..b7dd2d503 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -26,488 +26,114 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Gabe Black - * Stephen Hines + * Authors: Ali Saidi + * Gabe Black */ #include "arch/arm/faults.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "base/trace.hh" -#if !FULL_SYSTEM -#include "sim/process.hh" -#include "mem/page_table.hh" -#endif namespace ArmISA { -FaultName MachineCheckFault::_name = "Machine Check"; -FaultVect MachineCheckFault::_vect = 0x0401; -FaultStat MachineCheckFault::_count; +template<> ArmFaultBase::FaultVals ArmFault<Reset>::vals = + {"reset", 0x00, MODE_SVC, 0, 0, true, true}; -FaultName AlignmentFault::_name = "Alignment"; -FaultVect AlignmentFault::_vect = 0x0301; -FaultStat AlignmentFault::_count; +template<> ArmFaultBase::FaultVals ArmFault<UndefinedInstruction>::vals = + {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ; -FaultName ResetFault::_name = "Reset Fault"; -#if FULL_SYSTEM -FaultVect ResetFault::_vect = 0xBFC00000; -#else -FaultVect ResetFault::_vect = 0x001; -#endif -FaultStat ResetFault::_count; +template<> ArmFaultBase::FaultVals ArmFault<SupervisorCall>::vals = + {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false}; -FaultName AddressErrorFault::_name = "Address Error"; -FaultVect AddressErrorFault::_vect = 0x0180; -FaultStat AddressErrorFault::_count; +template<> ArmFaultBase::FaultVals ArmFault<PrefetchAbort>::vals = + {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false}; -FaultName StoreAddressErrorFault::_name = "Store Address Error"; -FaultVect StoreAddressErrorFault::_vect = 0x0180; -FaultStat StoreAddressErrorFault::_count; +template<> ArmFaultBase::FaultVals ArmFault<DataAbort>::vals = + {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false}; +template<> ArmFaultBase::FaultVals ArmFault<Interrupt>::vals = + {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false}; -FaultName SystemCallFault::_name = "Syscall"; -FaultVect SystemCallFault::_vect = 0x0180; -FaultStat SystemCallFault::_count; +template<> ArmFaultBase::FaultVals ArmFault<FastInterrupt>::vals = + {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true}; -FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault"; -FaultVect CoprocessorUnusableFault::_vect = 0x180; -FaultStat CoprocessorUnusableFault::_count; - -FaultName ReservedInstructionFault::_name = "Reserved Instruction Fault"; -FaultVect ReservedInstructionFault::_vect = 0x0180; -FaultStat ReservedInstructionFault::_count; - -FaultName ThreadFault::_name = "Thread Fault"; -FaultVect ThreadFault::_vect = 0x00F1; -FaultStat ThreadFault::_count; - - -FaultName ArithmeticFault::_name = "Arithmetic Overflow Exception"; -FaultVect ArithmeticFault::_vect = 0x180; -FaultStat ArithmeticFault::_count; - -FaultName UnimplementedOpcodeFault::_name = "opdec"; -FaultVect UnimplementedOpcodeFault::_vect = 0x0481; -FaultStat UnimplementedOpcodeFault::_count; - -FaultName InterruptFault::_name = "interrupt"; -FaultVect InterruptFault::_vect = 0x0180; -FaultStat InterruptFault::_count; - -FaultName TrapFault::_name = "Trap"; -FaultVect TrapFault::_vect = 0x0180; -FaultStat TrapFault::_count; - -FaultName BreakpointFault::_name = "Breakpoint"; -FaultVect BreakpointFault::_vect = 0x0180; -FaultStat BreakpointFault::_count; - - -FaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)"; -FaultVect ItbInvalidFault::_vect = 0x0180; -FaultStat ItbInvalidFault::_count; - -FaultName ItbPageFault::_name = "itbmiss"; -FaultVect ItbPageFault::_vect = 0x0181; -FaultStat ItbPageFault::_count; - -FaultName ItbMissFault::_name = "itbmiss"; -FaultVect ItbMissFault::_vect = 0x0181; -FaultStat ItbMissFault::_count; - -FaultName ItbAcvFault::_name = "iaccvio"; -FaultVect ItbAcvFault::_vect = 0x0081; -FaultStat ItbAcvFault::_count; - -FaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)"; -FaultVect ItbRefillFault::_vect = 0x0180; -FaultStat ItbRefillFault::_count; - -FaultName NDtbMissFault::_name = "dtb_miss_single"; -FaultVect NDtbMissFault::_vect = 0x0201; -FaultStat NDtbMissFault::_count; - -FaultName PDtbMissFault::_name = "dtb_miss_double"; -FaultVect PDtbMissFault::_vect = 0x0281; -FaultStat PDtbMissFault::_count; - -FaultName DtbPageFault::_name = "dfault"; -FaultVect DtbPageFault::_vect = 0x0381; -FaultStat DtbPageFault::_count; - -FaultName DtbAcvFault::_name = "dfault"; -FaultVect DtbAcvFault::_vect = 0x0381; -FaultStat DtbAcvFault::_count; - -FaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)"; -FaultVect DtbInvalidFault::_vect = 0x0180; -FaultStat DtbInvalidFault::_count; - -FaultName DtbRefillFault::_name = "TLB Refill Exception (Store)"; -FaultVect DtbRefillFault::_vect = 0x0180; -FaultStat DtbRefillFault::_count; - -FaultName TLBModifiedFault::_name = "TLB Modified Exception"; -FaultVect TLBModifiedFault::_vect = 0x0180; -FaultStat TLBModifiedFault::_count; - -FaultName FloatEnableFault::_name = "float_enable_fault"; -FaultVect FloatEnableFault::_vect = 0x0581; -FaultStat FloatEnableFault::_count; - -FaultName IntegerOverflowFault::_name = "Integer Overflow Fault"; -FaultVect IntegerOverflowFault::_vect = 0x0501; -FaultStat IntegerOverflowFault::_count; - -FaultName DspStateDisabledFault::_name = "DSP Disabled Fault"; -FaultVect DspStateDisabledFault::_vect = 0x001a; -FaultStat DspStateDisabledFault::_count; - -#if FULL_SYSTEM -void ArmFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc) -{ - tc->setPC(HandlerBase); - tc->setNextPC(HandlerBase+sizeof(MachInst)); - tc->setNextNPC(HandlerBase+2*sizeof(MachInst)); -} - -void ArmFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode) -{ - // modify SRS Ctl - Save CSS, put ESS into CSS - MiscReg stat = tc->readMiscReg(ArmISA::Status); - if(bits(stat,Status_EXL) != 1 && bits(stat,Status_BEV) != 1) - { - // SRS Ctl is modified only if Status_EXL and Status_BEV are not set - MiscReg srs = tc->readMiscReg(ArmISA::SRSCtl); - uint8_t CSS,ESS; - CSS = bits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO); - ESS = bits(srs,SRSCtl_ESS_HI,SRSCtl_ESS_LO); - // Move CSS to PSS - replaceBits(srs,SRSCtl_PSS_HI,SRSCtl_PSS_LO,CSS); - // Move ESS to CSS - replaceBits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO,ESS); - tc->setMiscRegNoEffect(ArmISA::SRSCtl,srs); - //tc->setShadowSet(ESS); - } - - // set EXL bit (don't care if it is already set!) - replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1); - tc->setMiscRegNoEffect(ArmISA::Status,stat); - - // write EPC - // warn("Set EPC to %x\n",tc->readPC()); - // CHECK ME or FIXME or FIX ME or POSSIBLE HACK - // Check to see if the exception occurred in the branch delay slot - DPRINTF(Arm,"PC: %x, NextPC: %x, NNPC: %x\n",tc->readPC(),tc->readNextPC(),tc->readNextNPC()); - int C_BD=0; - if(tc->readPC() + sizeof(MachInst) != tc->readNextPC()){ - tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()-sizeof(MachInst)); - // In the branch delay slot? set CAUSE_31 - C_BD = 1; - } else { - tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()); - // In the branch delay slot? reset CAUSE_31 - C_BD = 0; - } - - // Set Cause_EXCCODE field - MiscReg cause = tc->readMiscReg(ArmISA::Cause); - replaceBits(cause,Cause_EXCCODE_HI,Cause_EXCCODE_LO,ExcCode); - replaceBits(cause,Cause_BD_HI,Cause_BD_LO,C_BD); - replaceBits(cause,Cause_CE_HI,Cause_CE_LO,0); - tc->setMiscRegNoEffect(ArmISA::Cause,cause); - -} - -void ArithmeticFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0xC); - - // Set new PC - Addr HandlerBase; - MiscReg stat = tc->readMiscReg(ArmISA::Status); - // Here, the handler is dependent on BEV, which is not modified by setExceptionState() - if(bits(stat,Status_BEV)==0){ // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); - }else{ - HandlerBase = 0xBFC00200; - } - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); -} - -void StoreAddressErrorFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x5); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void TrapFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - // warn("%s encountered.\n", name()); - setExceptionState(tc,0xD); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); -} - -void BreakpointFault::invoke(ThreadContext *tc) -{ - setExceptionState(tc,0x9); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void DtbInvalidFault::invoke(ThreadContext *tc) +Addr +ArmFaultBase::getVector(ThreadContext *tc) { - DPRINTF(Arm,"%s encountered.\n", name()); - // warn("%s encountered.\n", name()); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - setExceptionState(tc,0x3); + // ARM ARM B1-3 + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + + // panic if SCTLR.VE because I have no idea what to do with vectored + // interrupts + assert(!sctlr.ve); + + if (!sctlr.v) + return offset(); + return offset() + HighVecs; - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); } -void AddressErrorFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x4); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); -} - -void ItbInvalidFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x2); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - DPRINTF(Arm,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); -} - -void ItbRefillFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered (%x).\n", name(),BadVAddr); - Addr HandlerBase; - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - MiscReg stat = tc->readMiscReg(ArmISA::Status); - // Since handler depends on EXL bit, must check EXL bit before setting it!! - if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - }else{ - HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000 - } - - setExceptionState(tc,0x2); - setHandlerPC(HandlerBase,tc); -} - -void DtbRefillFault::invoke(ThreadContext *tc) -{ - // Set new PC - DPRINTF(Arm,"%s encountered.\n", name()); - Addr HandlerBase; - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - MiscReg stat = tc->readMiscReg(ArmISA::Status); - // Since handler depends on EXL bit, must check EXL bit before setting it!! - if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - }else{ - HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000 - } - - - setExceptionState(tc,0x3); - - setHandlerPC(HandlerBase,tc); -} - -void TLBModifiedFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setExceptionState(tc,0x1); - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void SystemCallFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x8); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void InterruptFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x0A); - Addr HandlerBase; - - - uint8_t IV = bits(tc->readMiscRegNoEffect(ArmISA::Cause),Cause_IV); - if (IV)// Offset 200 for release 2 - HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(ArmISA::EBase); - else//Ofset at 180 for release 1 - HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); - - setHandlerPC(HandlerBase,tc); -#endif -} - -#endif // FULL_SYSTEM - -void ResetFault::invoke(ThreadContext *tc) -{ #if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - /* All reset activity must be invoked from here */ - tc->setPC(vect()); - tc->setNextPC(vect()+sizeof(MachInst)); - tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst)); - DPRINTF(Arm,"(%x) - ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC()); -#endif - // Set Coprocessor 1 (Floating Point) To Usable - //tc->setMiscReg(ArmISA::Status, ArmISA::Status | 0x20000000); -} - -void ReservedInstructionFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x0A); - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); -#else - panic("%s encountered.\n", name()); -#endif -} - -void ThreadFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - panic("%s encountered.\n", name()); -} - -void DspStateDisabledFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - panic("%s encountered.\n", name()); +void +ArmFaultBase::invoke(ThreadContext *tc) +{ + // ARM ARM B1.6.3 + FaultBase::invoke(tc); + countStat()++; + + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); + CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) | + tc->readIntReg(INTREG_CONDCODES); + + + cpsr.mode = nextMode(); + cpsr.it1 = cpsr.it2 = 0; + cpsr.j = 0; + + if (sctlr.te) + cpsr.t = 1; + cpsr.a = cpsr.a | abortDisable(); + cpsr.f = cpsr.f | fiqDisable(); + cpsr.i = 1; + tc->setMiscReg(MISCREG_CPSR, cpsr); + tc->setIntReg(INTREG_LR, tc->readPC() + + (saved_cpsr.t ? thumbPcOffset() : armPcOffset())); + + switch (nextMode()) { + case MODE_FIQ: + tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); + break; + case MODE_IRQ: + tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); + break; + case MODE_SVC: + tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); + break; + case MODE_UNDEFINED: + tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); + break; + case MODE_ABORT: + tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); + break; + default: + panic("unknown Mode\n"); + } + + DPRINTF(Faults, "Invoking Fault: %s cpsr: %#x PC: %#x lr: %#x\n", name(), cpsr, + tc->readPC(), tc->readIntReg(INTREG_LR)); + tc->setPC(getVector(tc)); + tc->setNextPC(getVector(tc) + cpsr.t ? 2 : 4 ); } +#endif // FULL_SYSTEM -void CoprocessorUnusableFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0xb); - /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */ - MiscReg cause = tc->readMiscReg(ArmISA::Cause); - replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID); - tc->setMiscRegNoEffect(ArmISA::Cause,cause); +// return via SUBS pc, lr, xxx; rfe, movs, ldm - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Status: %x, Cause: %x\n",tc->readMiscReg(ArmISA::Status),tc->readMiscReg(ArmISA::Cause)); -#else - warn("%s (CP%d) encountered.\n", name(), coProcID); -#endif -} } // namespace ArmISA diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh index 28ecd7591..7f8aa66b6 100644 --- a/src/arch/arm/faults.hh +++ b/src/arch/arm/faults.hh @@ -26,548 +26,79 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Gabe Black - * Stephen Hines + * Authors: Ali Saidi + * Gabe Black */ #ifndef __ARM_FAULTS_HH__ #define __ARM_FAULTS_HH__ +#include "arch/arm/types.hh" +#include "config/full_system.hh" #include "sim/faults.hh" // The design of the "name" and "vect" functions is in sim/faults.hh namespace ArmISA { -typedef const Addr FaultVect; +typedef const Addr FaultOffset; -class ArmFault : public FaultBase +class ArmFaultBase : public FaultBase { protected: - virtual bool skipFaultingInstruction() {return false;} - virtual bool setRestartAddress() {return true;} - public: - Addr BadVAddr; - Addr EntryHi_Asid; - Addr EntryHi_VPN2; - Addr EntryHi_VPN2X; - Addr Context_BadVPN2; -#if FULL_SYSTEM - void invoke(ThreadContext * tc) {}; - void setExceptionState(ThreadContext *,uint8_t); - void setHandlerPC(Addr,ThreadContext *); -#endif - virtual FaultVect vect() = 0; - virtual FaultStat & countStat() = 0; -}; - -class MachineCheckFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isMachineCheckFault() {return true;} -}; - -class NonMaskableInterrupt : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isNonMaskableInterrupt() {return true;} -}; - -class AlignmentFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isAlignmentFault() {return true;} -}; - -class AddressErrorFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; -class StoreAddressErrorFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; -class UnimplementedOpcodeFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - - -class TLBRefillIFetchFault : public ArmFault -{ - private: - Addr vaddr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; -class TLBInvalidIFetchFault : public ArmFault -{ - private: - Addr vaddr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class NDtbMissFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class PDtbMissFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class DtbPageFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class DtbAcvFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class CacheErrorFault : public ArmFault -{ - private: - Addr vaddr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - - - - -static inline Fault genMachineCheckFault() -{ - return new MachineCheckFault; -} - -static inline Fault genAlignmentFault() -{ - return new AlignmentFault; -} - -class ResetFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); - -}; -class SystemCallFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class SoftResetFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; -class DebugSingleStep : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; -class DebugInterrupt : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class CoprocessorUnusableFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - int coProcID; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); - CoprocessorUnusableFault(int _procid){ coProcID = _procid;} -}; + Addr getVector(ThreadContext *tc); -class ReservedInstructionFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class ThreadFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; + struct FaultVals + { + const FaultName name; + const FaultOffset offset; + const OperatingMode nextMode; + const uint8_t armPcOffset; + const uint8_t thumbPcOffset; + const bool abortDisable; + const bool fiqDisable; + FaultStat count; + }; - -class ArithmeticFault : public ArmFault -{ - protected: - bool skipFaultingInstruction() {return true;} - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} #if FULL_SYSTEM - void invoke(ThreadContext * tc); + void invoke(ThreadContext *tc); #endif + virtual FaultStat& countStat() = 0; + virtual FaultOffset offset() = 0; + virtual OperatingMode nextMode() = 0; + virtual uint8_t armPcOffset() = 0; + virtual uint8_t thumbPcOffset() = 0; + virtual bool abortDisable() = 0; + virtual bool fiqDisable() = 0; }; -class InterruptFault : public ArmFault +template<typename T> +class ArmFault : public ArmFaultBase { protected: - bool setRestartAddress() {return false;} - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - - //void invoke(ThreadContext * tc); -}; - -class TrapFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class BreakpointFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class ItbRefillFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; -class DtbRefillFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class ItbPageFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class ItbInvalidFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; -class TLBModifiedFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; + static FaultVals vals; -class DtbInvalidFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - + FaultName name() const { return vals.name; } + FaultStat & countStat() {return vals.count;} + FaultOffset offset() { return vals.offset; } + OperatingMode nextMode() { return vals.nextMode; } + uint8_t armPcOffset() { return vals.armPcOffset; } + uint8_t thumbPcOffset() { return vals.thumbPcOffset; } + bool abortDisable() { return vals.abortDisable; } + bool fiqDisable() { return vals.fiqDisable; } }; -class FloatEnableFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; -class ItbMissFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; +class Reset : public ArmFault<Reset> {}; +class UndefinedInstruction : public ArmFault<UndefinedInstruction> {}; +class SupervisorCall : public ArmFault<SupervisorCall> {}; +class PrefetchAbort : public ArmFault<PrefetchAbort> {}; +class DataAbort : public ArmFault<DataAbort> {}; +class Interrupt : public ArmFault<Interrupt> {}; +class FastInterrupt : public ArmFault<FastInterrupt> {}; -class ItbAcvFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class IntegerOverflowFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class DspStateDisabledFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; } // ArmISA namespace diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh index 541c9e3f5..714b8bb7e 100644 --- a/src/arch/arm/insts/macromem.hh +++ b/src/arch/arm/insts/macromem.hh @@ -84,33 +84,20 @@ class MicroMemOp : public MicroIntOp */ class ArmMacroMemoryOp : public PredMacroOp { - protected: + protected: /// Memory request flags. See mem_req_base.hh. unsigned memAccessFlags; uint32_t reglist; uint32_t ones; - uint32_t puswl, - prepost, - up, - psruser, - writeback, - loadop; ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) - : PredMacroOp(mnem, _machInst, __opClass), - memAccessFlags(0), - reglist(machInst.regList), ones(0), - puswl(machInst.puswl), - prepost(machInst.puswl.prepost), - up(machInst.puswl.up), - psruser(machInst.puswl.psruser), - writeback(machInst.puswl.writeback), - loadop(machInst.puswl.loadOp) + : PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0), + reglist(machInst.regList), ones(0) { ones = number_of_ones(reglist); - numMicroops = ones + writeback + 1; + numMicroops = ones + machInst.puswl.writeback + 1; // Remember that writeback adds a uop microOps = new StaticInstPtr[numMicroops]; } @@ -121,7 +108,7 @@ class ArmMacroMemoryOp : public PredMacroOp */ class ArmMacroFPAOp : public PredMacroOp { - protected: + protected: uint32_t puswl, prepost, up, @@ -150,7 +137,7 @@ class ArmMacroFPAOp : public PredMacroOp */ class ArmMacroFMOp : public PredMacroOp { - protected: + protected: uint32_t punwl, prepost, up, diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index df2d5de25..bf7a38c58 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -27,8 +27,10 @@ * Authors: Stephen Hines */ +#include "arch/arm/faults.hh" #include "arch/arm/insts/static_inst.hh" #include "base/condcodes.hh" +#include "base/cprintf.hh" #include "base/loader/symtab.hh" namespace ArmISA @@ -62,7 +64,7 @@ ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt, else return (base << (32 - shamt)) | (base >> shamt); default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } @@ -101,7 +103,7 @@ ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt, else return (base << (32 - shamt)) | (base >> shamt); default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } @@ -141,7 +143,7 @@ ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt, else return (base >> (shamt - 1)) & 1; default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } @@ -182,7 +184,7 @@ ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt, shamt = 32; return (base >> (shamt - 1)) & 1; default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index c963c1827..f2881c3b6 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -74,6 +74,56 @@ class ArmStaticInst : public StaticInst void printDataInst(std::ostream &os, bool withImm) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + static uint32_t + cpsrWriteByInstr(CPSR cpsr, uint32_t val, + uint8_t byteMask, bool affectState) + { + bool privileged = (cpsr.mode != MODE_USER); + + uint32_t bitMask = 0; + + if (bits(byteMask, 3)) { + unsigned lowIdx = affectState ? 24 : 27; + bitMask = bitMask | mask(31, lowIdx); + } + if (bits(byteMask, 2)) { + bitMask = bitMask | mask(19, 16); + } + if (bits(byteMask, 1)) { + unsigned highIdx = affectState ? 15 : 9; + unsigned lowIdx = privileged ? 8 : 9; + bitMask = bitMask | mask(highIdx, lowIdx); + } + if (bits(byteMask, 0)) { + if (privileged) { + bitMask = bitMask | mask(7, 6); + bitMask = bitMask | mask(5); + } + if (affectState) + bitMask = bitMask | (1 << 5); + } + + return ((uint32_t)cpsr & ~bitMask) | (val & bitMask); + } + + static uint32_t + spsrWriteByInstr(uint32_t spsr, uint32_t val, + uint8_t byteMask, bool affectState) + { + uint32_t bitMask = 0; + + if (bits(byteMask, 3)) + bitMask = bitMask | mask(31, 24); + if (bits(byteMask, 2)) + bitMask = bitMask | mask(19, 16); + if (bits(byteMask, 1)) + bitMask = bitMask | mask(15, 8); + if (bits(byteMask, 0)) + bitMask = bitMask | mask(7, 0); + + return ((spsr & ~bitMask) | (val & bitMask)); + } }; } diff --git a/src/mem/slicc/ast/AST.cc b/src/arch/arm/interrupts.cc index e893c453a..a47ebc75d 100644 --- a/src/mem/slicc/ast/AST.cc +++ b/src/arch/arm/interrupts.cc @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 ARM Limited * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,15 +24,14 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * AST.C - * - * Description: See AST.hh - * - * $Id$ * + * Authors: Ali Saidi */ -#include "mem/slicc/ast/AST.hh" +#include "arch/arm/interrupts.hh" + +ArmISA::Interrupts * +ArmInterruptsParams::create() +{ + return new ArmISA::Interrupts(this); +} diff --git a/src/mem/slicc/ast/LiteralExprAST.hh b/src/arch/arm/interrupts.hh index c895fa9ae..189341d6b 100644 --- a/src/mem/slicc/ast/LiteralExprAST.hh +++ b/src/arch/arm/interrupts.hh @@ -1,6 +1,6 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2009 ARM Limited * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,59 +25,97 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * LiteralExprAST.hh - * - * Description: - * - * $Id: LiteralExprAST.hh,v 3.1 2001/12/12 01:00:20 milo Exp $ * + * Authors: Ali Saidi */ -#ifndef LITERALEXPRAST_H -#define LITERALEXPRAST_H +#ifndef __ARCH_ARM_INTERRUPT_HH__ +#define __ARCH_ARM_INTERRUPT_HH__ -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" +#include "arch/arm/faults.hh" +#include "arch/arm/isa_traits.hh" +#include "arch/arm/registers.hh" +#include "cpu/thread_context.hh" +#include "params/ArmInterrupts.hh" +#include "sim/sim_object.hh" +namespace ArmISA +{ -class LiteralExprAST : public ExprAST { -public: - // Constructors - LiteralExprAST(string* lit_ptr, string type) : ExprAST() { m_lit_ptr = lit_ptr; m_type = type; } +class Interrupts : public SimObject +{ + private: + BaseCPU * cpu; - // Destructor - ~LiteralExprAST() { delete m_lit_ptr; } + uint64_t intStatus; - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const { out << "[Literal: " << *m_lit_ptr << "]"; } -private: - // Private Methods + public: - // Private copy constructor and assignment operator - LiteralExprAST(const LiteralExprAST& obj); - LiteralExprAST& operator=(const LiteralExprAST& obj); + void + setCPU(BaseCPU * _cpu) + { + cpu = _cpu; + } - // Data Members (m_ prefix) - string* m_lit_ptr; - string m_type; -}; + typedef ArmInterruptsParams Params; -// Output operator declaration -ostream& operator<<(ostream& out, const LiteralExprAST& obj); + const Params * + params() const + { + return dynamic_cast<const Params *>(_params); + } -// ******************* Definitions ******************* + Interrupts(Params * p) : SimObject(p), cpu(NULL) + { + clearAll(); + } -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const LiteralExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} -#endif //LITERALEXPRAST_H + void + post(int int_num, int index) + { + } + + void + clear(int int_num, int index) + { + } + + void + clearAll() + { + intStatus = 0; + } + + bool + checkInterrupts(ThreadContext *tc) const + { + return intStatus; + } + + Fault + getInterrupt(ThreadContext *tc) + { + warn_once("ARM Interrupts not handled\n"); + return NoFault; + } + + void + updateIntrInfo(ThreadContext *tc) + { + + } + + void + serialize(std::ostream &os) + { + } + + void + unserialize(Checkpoint *cp, const std::string §ion) + { + } +}; +} // namespace ARM_ISA + +#endif // __ARCH_ARM_INTERRUPT_HH__ diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh new file mode 100644 index 000000000..15499601a --- /dev/null +++ b/src/arch/arm/intregs.hh @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2009 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include <assert.h> + +#ifndef __ARCH_ARM_INTREGS_HH__ +#define __ARCH_ARM_INTREGS_HH__ + +namespace ArmISA +{ + +enum IntRegIndex +{ + /* All the unique register indices. */ + INTREG_R0, + INTREG_R1, + INTREG_R2, + INTREG_R3, + INTREG_R4, + INTREG_R5, + INTREG_R6, + INTREG_R7, + INTREG_R8, + INTREG_R9, + INTREG_R10, + INTREG_R11, + INTREG_R12, + INTREG_R13, + INTREG_SP = INTREG_R13, + INTREG_R14, + INTREG_LR = INTREG_R14, + INTREG_R15, + INTREG_PC = INTREG_R15, + + INTREG_R13_SVC, + INTREG_SP_SVC = INTREG_R13_SVC, + INTREG_R14_SVC, + INTREG_LR_SVC = INTREG_R14_SVC, + + INTREG_R13_MON, + INTREG_SP_MON = INTREG_R13_MON, + INTREG_R14_MON, + INTREG_LR_MON = INTREG_R14_MON, + + INTREG_R13_ABT, + INTREG_SP_ABT = INTREG_R13_ABT, + INTREG_R14_ABT, + INTREG_LR_ABT = INTREG_R14_ABT, + + INTREG_R13_UND, + INTREG_SP_UND = INTREG_R13_UND, + INTREG_R14_UND, + INTREG_LR_UND = INTREG_R14_UND, + + INTREG_R13_IRQ, + INTREG_SP_IRQ = INTREG_R13_IRQ, + INTREG_R14_IRQ, + INTREG_LR_IRQ = INTREG_R14_IRQ, + + INTREG_R8_FIQ, + INTREG_R9_FIQ, + INTREG_R10_FIQ, + INTREG_R11_FIQ, + INTREG_R12_FIQ, + INTREG_R13_FIQ, + INTREG_SP_FIQ = INTREG_R13_FIQ, + INTREG_R14_FIQ, + INTREG_LR_FIQ = INTREG_R14_FIQ, + + INTREG_ZERO, // Dummy zero reg since there has to be one. + INTREG_UREG0, + INTREG_RHI, + INTREG_RLO, + INTREG_CONDCODES, + + NUM_INTREGS, + NUM_ARCH_INTREGS = INTREG_PC + 1, + + /* All the aliased indexes. */ + + /* USR mode */ + INTREG_R0_USR = INTREG_R0, + INTREG_R1_USR = INTREG_R1, + INTREG_R2_USR = INTREG_R2, + INTREG_R3_USR = INTREG_R3, + INTREG_R4_USR = INTREG_R4, + INTREG_R5_USR = INTREG_R5, + INTREG_R6_USR = INTREG_R6, + INTREG_R7_USR = INTREG_R7, + INTREG_R8_USR = INTREG_R8, + INTREG_R9_USR = INTREG_R9, + INTREG_R10_USR = INTREG_R10, + INTREG_R11_USR = INTREG_R11, + INTREG_R12_USR = INTREG_R12, + INTREG_R13_USR = INTREG_R13, + INTREG_SP_USR = INTREG_SP, + INTREG_R14_USR = INTREG_R14, + INTREG_LR_USR = INTREG_LR, + INTREG_R15_USR = INTREG_R15, + INTREG_PC_USR = INTREG_PC, + + /* SVC mode */ + INTREG_R0_SVC = INTREG_R0, + INTREG_R1_SVC = INTREG_R1, + INTREG_R2_SVC = INTREG_R2, + INTREG_R3_SVC = INTREG_R3, + INTREG_R4_SVC = INTREG_R4, + INTREG_R5_SVC = INTREG_R5, + INTREG_R6_SVC = INTREG_R6, + INTREG_R7_SVC = INTREG_R7, + INTREG_R8_SVC = INTREG_R8, + INTREG_R9_SVC = INTREG_R9, + INTREG_R10_SVC = INTREG_R10, + INTREG_R11_SVC = INTREG_R11, + INTREG_R12_SVC = INTREG_R12, + INTREG_PC_SVC = INTREG_PC, + INTREG_R15_SVC = INTREG_R15, + + /* MON mode */ + INTREG_R0_MON = INTREG_R0, + INTREG_R1_MON = INTREG_R1, + INTREG_R2_MON = INTREG_R2, + INTREG_R3_MON = INTREG_R3, + INTREG_R4_MON = INTREG_R4, + INTREG_R5_MON = INTREG_R5, + INTREG_R6_MON = INTREG_R6, + INTREG_R7_MON = INTREG_R7, + INTREG_R8_MON = INTREG_R8, + INTREG_R9_MON = INTREG_R9, + INTREG_R10_MON = INTREG_R10, + INTREG_R11_MON = INTREG_R11, + INTREG_R12_MON = INTREG_R12, + INTREG_PC_MON = INTREG_PC, + INTREG_R15_MON = INTREG_R15, + + /* ABT mode */ + INTREG_R0_ABT = INTREG_R0, + INTREG_R1_ABT = INTREG_R1, + INTREG_R2_ABT = INTREG_R2, + INTREG_R3_ABT = INTREG_R3, + INTREG_R4_ABT = INTREG_R4, + INTREG_R5_ABT = INTREG_R5, + INTREG_R6_ABT = INTREG_R6, + INTREG_R7_ABT = INTREG_R7, + INTREG_R8_ABT = INTREG_R8, + INTREG_R9_ABT = INTREG_R9, + INTREG_R10_ABT = INTREG_R10, + INTREG_R11_ABT = INTREG_R11, + INTREG_R12_ABT = INTREG_R12, + INTREG_PC_ABT = INTREG_PC, + INTREG_R15_ABT = INTREG_R15, + + /* UND mode */ + INTREG_R0_UND = INTREG_R0, + INTREG_R1_UND = INTREG_R1, + INTREG_R2_UND = INTREG_R2, + INTREG_R3_UND = INTREG_R3, + INTREG_R4_UND = INTREG_R4, + INTREG_R5_UND = INTREG_R5, + INTREG_R6_UND = INTREG_R6, + INTREG_R7_UND = INTREG_R7, + INTREG_R8_UND = INTREG_R8, + INTREG_R9_UND = INTREG_R9, + INTREG_R10_UND = INTREG_R10, + INTREG_R11_UND = INTREG_R11, + INTREG_R12_UND = INTREG_R12, + INTREG_PC_UND = INTREG_PC, + INTREG_R15_UND = INTREG_R15, + + /* IRQ mode */ + INTREG_R0_IRQ = INTREG_R0, + INTREG_R1_IRQ = INTREG_R1, + INTREG_R2_IRQ = INTREG_R2, + INTREG_R3_IRQ = INTREG_R3, + INTREG_R4_IRQ = INTREG_R4, + INTREG_R5_IRQ = INTREG_R5, + INTREG_R6_IRQ = INTREG_R6, + INTREG_R7_IRQ = INTREG_R7, + INTREG_R8_IRQ = INTREG_R8, + INTREG_R9_IRQ = INTREG_R9, + INTREG_R10_IRQ = INTREG_R10, + INTREG_R11_IRQ = INTREG_R11, + INTREG_R12_IRQ = INTREG_R12, + INTREG_PC_IRQ = INTREG_PC, + INTREG_R15_IRQ = INTREG_R15, + + /* FIQ mode */ + INTREG_R0_FIQ = INTREG_R0, + INTREG_R1_FIQ = INTREG_R1, + INTREG_R2_FIQ = INTREG_R2, + INTREG_R3_FIQ = INTREG_R3, + INTREG_R4_FIQ = INTREG_R4, + INTREG_R5_FIQ = INTREG_R5, + INTREG_R6_FIQ = INTREG_R6, + INTREG_R7_FIQ = INTREG_R7, + INTREG_PC_FIQ = INTREG_PC, + INTREG_R15_FIQ = INTREG_R15, +}; + +typedef IntRegIndex IntRegMap[NUM_ARCH_INTREGS]; + +const IntRegMap IntRegUsrMap = { + INTREG_R0_USR, INTREG_R1_USR, INTREG_R2_USR, INTREG_R3_USR, + INTREG_R4_USR, INTREG_R5_USR, INTREG_R6_USR, INTREG_R7_USR, + INTREG_R8_USR, INTREG_R9_USR, INTREG_R10_USR, INTREG_R11_USR, + INTREG_R12_USR, INTREG_R13_USR, INTREG_R14_USR, INTREG_R15_USR +}; + +static inline IntRegIndex +INTREG_USR(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegUsrMap[index]; +} + +const IntRegMap IntRegSvcMap = { + INTREG_R0_SVC, INTREG_R1_SVC, INTREG_R2_SVC, INTREG_R3_SVC, + INTREG_R4_SVC, INTREG_R5_SVC, INTREG_R6_SVC, INTREG_R7_SVC, + INTREG_R8_SVC, INTREG_R9_SVC, INTREG_R10_SVC, INTREG_R11_SVC, + INTREG_R12_SVC, INTREG_R13_SVC, INTREG_R14_SVC, INTREG_R15_SVC +}; + +static inline IntRegIndex +INTREG_SVC(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegSvcMap[index]; +} + +const IntRegMap IntRegMonMap = { + INTREG_R0_MON, INTREG_R1_MON, INTREG_R2_MON, INTREG_R3_MON, + INTREG_R4_MON, INTREG_R5_MON, INTREG_R6_MON, INTREG_R7_MON, + INTREG_R8_MON, INTREG_R9_MON, INTREG_R10_MON, INTREG_R11_MON, + INTREG_R12_MON, INTREG_R13_MON, INTREG_R14_MON, INTREG_R15_MON +}; + +static inline IntRegIndex +INTREG_MON(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegMonMap[index]; +} + +const IntRegMap IntRegAbtMap = { + INTREG_R0_ABT, INTREG_R1_ABT, INTREG_R2_ABT, INTREG_R3_ABT, + INTREG_R4_ABT, INTREG_R5_ABT, INTREG_R6_ABT, INTREG_R7_ABT, + INTREG_R8_ABT, INTREG_R9_ABT, INTREG_R10_ABT, INTREG_R11_ABT, + INTREG_R12_ABT, INTREG_R13_ABT, INTREG_R14_ABT, INTREG_R15_ABT +}; + +static inline IntRegIndex +INTREG_ABT(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegAbtMap[index]; +} + +const IntRegMap IntRegUndMap = { + INTREG_R0_UND, INTREG_R1_UND, INTREG_R2_UND, INTREG_R3_UND, + INTREG_R4_UND, INTREG_R5_UND, INTREG_R6_UND, INTREG_R7_UND, + INTREG_R8_UND, INTREG_R9_UND, INTREG_R10_UND, INTREG_R11_UND, + INTREG_R12_UND, INTREG_R13_UND, INTREG_R14_UND, INTREG_R15_UND +}; + +static inline IntRegIndex +INTREG_UND(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegUndMap[index]; +} + +const IntRegMap IntRegIrqMap = { + INTREG_R0_IRQ, INTREG_R1_IRQ, INTREG_R2_IRQ, INTREG_R3_IRQ, + INTREG_R4_IRQ, INTREG_R5_IRQ, INTREG_R6_IRQ, INTREG_R7_IRQ, + INTREG_R8_IRQ, INTREG_R9_IRQ, INTREG_R10_IRQ, INTREG_R11_IRQ, + INTREG_R12_IRQ, INTREG_R13_IRQ, INTREG_R14_IRQ, INTREG_R15_IRQ +}; + +static inline IntRegIndex +INTREG_IRQ(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegIrqMap[index]; +} + +const IntRegMap IntRegFiqMap = { + INTREG_R0_FIQ, INTREG_R1_FIQ, INTREG_R2_FIQ, INTREG_R3_FIQ, + INTREG_R4_FIQ, INTREG_R5_FIQ, INTREG_R6_FIQ, INTREG_R7_FIQ, + INTREG_R8_FIQ, INTREG_R9_FIQ, INTREG_R10_FIQ, INTREG_R11_FIQ, + INTREG_R12_FIQ, INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_R15_FIQ +}; + +static inline IntRegIndex +INTREG_FIQ(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegFiqMap[index]; +} + +static inline IntRegIndex +intRegForceUser(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + + return index == 15 ? (IntRegIndex)15 : (IntRegIndex)(index + NUM_INTREGS); +} + +} + +#endif diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 2315afa9e..905eb0183 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -44,6 +44,38 @@ namespace ArmISA { protected: MiscReg miscRegs[NumMiscRegs]; + const IntRegIndex *intRegMap; + + void + updateRegMap(CPSR cpsr) + { + switch (cpsr.mode) { + case MODE_USER: + case MODE_SYSTEM: + intRegMap = IntRegUsrMap; + break; + case MODE_FIQ: + intRegMap = IntRegFiqMap; + break; + case MODE_IRQ: + intRegMap = IntRegIrqMap; + break; + case MODE_SVC: + intRegMap = IntRegSvcMap; + break; + case MODE_MON: + intRegMap = IntRegMonMap; + break; + case MODE_ABORT: + intRegMap = IntRegAbtMap; + break; + case MODE_UNDEFINED: + intRegMap = IntRegUndMap; + break; + default: + panic("Unrecognized mode setting in CPSR.\n"); + } + } public: void clear() @@ -52,6 +84,15 @@ namespace ArmISA CPSR cpsr = 0; cpsr.mode = MODE_USER; miscRegs[MISCREG_CPSR] = cpsr; + updateRegMap(cpsr); + + SCTLR sctlr = 0; + sctlr.nmfi = 1; + sctlr.rao1 = 1; + sctlr.rao2 = 1; + sctlr.rao3 = 1; + sctlr.rao4 = 1; + //XXX We need to initialize the rest of the state. } @@ -59,34 +100,94 @@ namespace ArmISA readMiscRegNoEffect(int misc_reg) { assert(misc_reg < NumMiscRegs); + if (misc_reg == MISCREG_SPSR) { + CPSR cpsr = miscRegs[MISCREG_CPSR]; + switch (cpsr.mode) { + case MODE_USER: + return miscRegs[MISCREG_SPSR]; + case MODE_FIQ: + return miscRegs[MISCREG_SPSR_FIQ]; + case MODE_IRQ: + return miscRegs[MISCREG_SPSR_IRQ]; + case MODE_SVC: + return miscRegs[MISCREG_SPSR_SVC]; + case MODE_MON: + return miscRegs[MISCREG_SPSR_MON]; + case MODE_ABORT: + return miscRegs[MISCREG_SPSR_ABT]; + case MODE_UNDEFINED: + return miscRegs[MISCREG_SPSR_UND]; + default: + return miscRegs[MISCREG_SPSR]; + } + } return miscRegs[misc_reg]; } MiscReg readMiscReg(int misc_reg, ThreadContext *tc) { - assert(misc_reg < NumMiscRegs); - return miscRegs[misc_reg]; + return readMiscRegNoEffect(misc_reg); } void setMiscRegNoEffect(int misc_reg, const MiscReg &val) { assert(misc_reg < NumMiscRegs); + if (misc_reg == MISCREG_SPSR) { + CPSR cpsr = miscRegs[MISCREG_CPSR]; + switch (cpsr.mode) { + case MODE_USER: + miscRegs[MISCREG_SPSR] = val; + return; + case MODE_FIQ: + miscRegs[MISCREG_SPSR_FIQ] = val; + return; + case MODE_IRQ: + miscRegs[MISCREG_SPSR_IRQ] = val; + return; + case MODE_SVC: + miscRegs[MISCREG_SPSR_SVC] = val; + return; + case MODE_MON: + miscRegs[MISCREG_SPSR_MON] = val; + return; + case MODE_ABORT: + miscRegs[MISCREG_SPSR_ABT] = val; + return; + case MODE_UNDEFINED: + miscRegs[MISCREG_SPSR_UND] = val; + return; + default: + miscRegs[MISCREG_SPSR] = val; + return; + } + } miscRegs[misc_reg] = val; } void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) { - assert(misc_reg < NumMiscRegs); - miscRegs[misc_reg] = val; + if (misc_reg == MISCREG_CPSR) { + updateRegMap(val); + } + return setMiscRegNoEffect(misc_reg, val); } int flattenIntIndex(int reg) { - return reg; + assert(reg >= 0); + if (reg < NUM_ARCH_INTREGS) { + return intRegMap[reg]; + } else if (reg < NUM_INTREGS) { + return reg; + } else { + reg -= NUM_INTREGS; + assert(reg < NUM_ARCH_INTREGS); + return reg; + } } int @@ -95,9 +196,10 @@ namespace ArmISA return reg; } - void serialize(std::ostream &os) + void serialize(EventManager *em, std::ostream &os) {} - void unserialize(Checkpoint *cp, const std::string §ion) + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion) {} ISA() diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index 5785939cc..8ff819983 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -38,14 +38,18 @@ def bitfield ENCODING encoding; def bitfield OPCODE opcode; def bitfield MEDIA_OPCODE mediaOpcode; def bitfield MEDIA_OPCODE2 mediaOpcode2; +def bitfield USEIMM useImm; def bitfield OPCODE_24 opcode24; def bitfield OPCODE_23_20 opcode23_20; def bitfield OPCODE_23_21 opcode23_21; def bitfield OPCODE_22 opcode22; +def bitfield OPCODE_20 opcode20; def bitfield OPCODE_19 opcode19; +def bitfield OPCODE_18 opcode18; def bitfield OPCODE_15_12 opcode15_12; def bitfield OPCODE_15 opcode15; def bitfield MISC_OPCODE miscOpcode; +def bitfield OPC2 opc2; def bitfield OPCODE_7 opcode7; def bitfield OPCODE_4 opcode4; diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index a999b52e9..ff20c6107 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -51,20 +51,25 @@ format DataOp { resTemp = ((uint64_t)Rm)*((uint64_t)Rs); Rd = (uint32_t)(resTemp & 0xffffffff); Rn = (uint32_t)(resTemp >> 32); - }}); - 0x5: WarnUnimpl::smlal(); + }}, llbit); + 0x5: smlal({{ + resTemp = ((int64_t)Rm) * ((int64_t)Rs); + resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd); + Rd = (uint32_t)(resTemp & 0xffffffff); + Rn = (uint32_t)(resTemp >> 32); + }}, llbit); 0x6: smull({{ resTemp = ((int64_t)(int32_t)Rm)* ((int64_t)(int32_t)Rs); Rd = (int32_t)(resTemp & 0xffffffff); Rn = (int32_t)(resTemp >> 32); - }}); + }}, llbit); 0x7: umlal({{ resTemp = ((uint64_t)Rm)*((uint64_t)Rs); resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd); Rd = (uint32_t)(resTemp & 0xffffffff); Rn = (uint32_t)(resTemp >> 32); - }}); + }}, llbit); } 1: decode PUBWL { 0x10: WarnUnimpl::swp(); @@ -91,9 +96,9 @@ format DataOp { 0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub); 0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb); 0x4: add({{ Rd = resTemp = Rn + op2; }}, add); - 0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add); - 0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub); - 0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb); + 0x5: adc({{ Rd = resTemp = Rn + op2 + CondCodes<29:>; }}, add); + 0x6: sbc({{ Rd = resTemp = Rn - op2 - !CondCodes<29:>; }}, sub); + 0x7: rsc({{ Rd = resTemp = op2 - Rn - !CondCodes<29:>; }}, rsb); 0x8: tst({{ resTemp = Rn & op2; }}); 0x9: teq({{ resTemp = Rn ^ op2; }}); 0xa: cmp({{ resTemp = Rn - op2; }}, sub); @@ -105,10 +110,37 @@ format DataOp { } 1: decode MISC_OPCODE { 0x0: decode OPCODE { - 0x8: WarnUnimpl::mrs_cpsr(); - 0x9: WarnUnimpl::msr_cpsr(); - 0xa: WarnUnimpl::mrs_spsr(); - 0xb: WarnUnimpl::msr_spsr(); + 0x8: PredOp::mrs_cpsr({{ + Rd = (Cpsr | CondCodes) & 0xF8FF03DF; + }}); + 0x9: decode USEIMM { + // The mask field is the same as the RN index. + 0: PredOp::msr_cpsr_reg({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + Rm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + 1: PredImmOp::msr_cpsr_imm({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + rotated_imm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + } + 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); + 0xb: decode USEIMM { + // The mask field is the same as the RN index. + 0: PredOp::msr_spsr_reg({{ + Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); + }}); + 1: PredImmOp::msr_spsr_imm({{ + Spsr = spsrWriteByInstr(Spsr, rotated_imm, + RN, false); + }}); + } } 0x1: decode OPCODE { 0x9: BranchExchange::bx({{ }}); @@ -129,28 +161,32 @@ format DataOp { 0xb: WarnUnimpl::qdsub(); } 0x8: decode OPCODE { - 0x8: WarnUnimpl::smlabb(); + 0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); 0x9: WarnUnimpl::smlalbb(); 0xa: WarnUnimpl::smlawb(); - 0xb: WarnUnimpl::smulbb(); + 0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none); } 0xa: decode OPCODE { - 0x8: WarnUnimpl::smlatb(); - 0x9: WarnUnimpl::smulwb(); + 0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); + 0x9: smulwb({{ + Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16); + }}, none); 0xa: WarnUnimpl::smlaltb(); - 0xb: WarnUnimpl::smultb(); + 0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none); } 0xc: decode OPCODE { - 0x8: WarnUnimpl::smlabt(); + 0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); 0x9: WarnUnimpl::smlawt(); 0xa: WarnUnimpl::smlalbt(); - 0xb: WarnUnimpl::smulbt(); + 0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none); } 0xe: decode OPCODE { - 0x8: WarnUnimpl::smlatt(); - 0x9: WarnUnimpl::smulwt(); + 0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); + 0x9: smulwt({{ + Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16); + }}, none); 0xa: WarnUnimpl::smlaltt(); - 0xb: WarnUnimpl::smultt(); + 0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none); } } } @@ -163,9 +199,15 @@ format DataOp { 0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub); 0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb); 0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add); - 0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add); - 0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub); - 0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb); + 0x5: adci({{ + Rd = resTemp = Rn + rotated_imm + CondCodes<29:>; + }}, add); + 0x6: sbci({{ + Rd = resTemp = Rn -rotated_imm - !CondCodes<29:>; + }}, sub); + 0x7: rsci({{ + Rd = resTemp = rotated_imm - Rn - !CondCodes<29:>; + }}, rsb); 0x8: tsti({{ resTemp = Rn & rotated_imm; }}); 0x9: teqi({{ resTemp = Rn ^ rotated_imm; }}); 0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub); @@ -178,11 +220,27 @@ format DataOp { } 1: decode OPCODE { // The following two instructions aren't supposed to be defined - 0x8: WarnUnimpl::undefined_instruction(); - 0x9: WarnUnimpl::undefined_instruction(); - - 0xa: WarnUnimpl::mrs_i_cpsr(); - 0xb: WarnUnimpl::mrs_i_spsr(); + 0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }}); + 0x9: decode RN { + 0: decode IMM { + 0: PredImmOp::nop({{ ; }}); + 1: WarnUnimpl::yield(); + 2: WarnUnimpl::wfe(); + 3: WarnUnimpl::wfi(); + 4: WarnUnimpl::sev(); + } + default: PredImmOp::msr_i_cpsr({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + rotated_imm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + } + 0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }}); + 0xb: PredImmOp::msr_i_spsr({{ + Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false); + }}); } } 0x2: AddrMode2::addrMode2(Disp, disp); @@ -324,77 +382,79 @@ format DataOp { } } 0x7: decode OPCODE_24 { - 0: decode CPNUM { - // Coprocessor Instructions - 0x1: decode OPCODE_4 { + 0: decode OPCODE_4 { + 0: decode CPNUM { format FloatOp { - // Basic FPA Instructions - 0: decode OPCODE_23_20 { - 0x0: decode OPCODE_15 { - 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }}); - 1: mvf({{ Fd.sf = Fm.sf; }}); - } - 0x1: decode OPCODE_15 { - 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }}); - 1: mnf({{ Fd.sf = -Fm.sf; }}); - } - 0x2: decode OPCODE_15 { - 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }}); - 1: abs({{ Fd.sf = fabs(Fm.sf); }}); - } - 0x3: decode OPCODE_15 { - 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }}); - 1: rnd({{ Fd.sf = rint(Fm.sf); }}); - } - 0x4: decode OPCODE_15 { - 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }}); - 1: sqt({{ Fd.sf = sqrt(Fm.sf); }}); - } - 0x5: decode OPCODE_15 { - 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }}); - 1: log({{ Fd.sf = log10(Fm.sf); }}); - } - 0x6: decode OPCODE_15 { - 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }}); - 1: lgn({{ Fd.sf = log(Fm.sf); }}); - } - 0x7: decode OPCODE_15 { - 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }}); - 1: exp({{ Fd.sf = exp(Fm.sf); }}); - } - 0x8: decode OPCODE_15 { - 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }}); - 1: sin({{ Fd.sf = sin(Fm.sf); }}); - } - 0x9: decode OPCODE_15 { - 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }}); - 1: cos({{ Fd.sf = cos(Fm.sf); }}); - } - 0xa: decode OPCODE_15 { - 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }}); - 1: tan({{ Fd.sf = tan(Fm.sf); }}); - } - 0xb: decode OPCODE_15 { - 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }}); - 1: asn({{ Fd.sf = asin(Fm.sf); }}); - } - 0xc: decode OPCODE_15 { - 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }}); - 1: acs({{ Fd.sf = acos(Fm.sf); }}); - } - 0xd: decode OPCODE_15 { - 1: atn({{ Fd.sf = atan(Fm.sf); }}); - } - 0xe: decode OPCODE_15 { - // Unnormalised Round - 1: FailUnimpl::urd(); - } - 0xf: decode OPCODE_15 { - // Normalise - 1: FailUnimpl::nrm(); - } - } - 1: decode OPCODE_15_12 { + 0x1: decode OPCODE_23_20 { + 0x0: decode OPCODE_15 { + 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }}); + 1: mvf({{ Fd.sf = Fm.sf; }}); + } + 0x1: decode OPCODE_15 { + 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }}); + 1: mnf({{ Fd.sf = -Fm.sf; }}); + } + 0x2: decode OPCODE_15 { + 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }}); + 1: abs({{ Fd.sf = fabs(Fm.sf); }}); + } + 0x3: decode OPCODE_15 { + 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }}); + 1: rnd({{ Fd.sf = rint(Fm.sf); }}); + } + 0x4: decode OPCODE_15 { + 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }}); + 1: sqt({{ Fd.sf = sqrt(Fm.sf); }}); + } + 0x5: decode OPCODE_15 { + 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }}); + 1: log({{ Fd.sf = log10(Fm.sf); }}); + } + 0x6: decode OPCODE_15 { + 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }}); + 1: lgn({{ Fd.sf = log(Fm.sf); }}); + } + 0x7: decode OPCODE_15 { + 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }}); + 1: exp({{ Fd.sf = exp(Fm.sf); }}); + } + 0x8: decode OPCODE_15 { + 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }}); + 1: sin({{ Fd.sf = sin(Fm.sf); }}); + } + 0x9: decode OPCODE_15 { + 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }}); + 1: cos({{ Fd.sf = cos(Fm.sf); }}); + } + 0xa: decode OPCODE_15 { + 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }}); + 1: tan({{ Fd.sf = tan(Fm.sf); }}); + } + 0xb: decode OPCODE_15 { + 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }}); + 1: asn({{ Fd.sf = asin(Fm.sf); }}); + } + 0xc: decode OPCODE_15 { + 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }}); + 1: acs({{ Fd.sf = acos(Fm.sf); }}); + } + 0xd: decode OPCODE_15 { + 1: atn({{ Fd.sf = atan(Fm.sf); }}); + } + 0xe: decode OPCODE_15 { + // Unnormalised Round + 1: FailUnimpl::urd(); + } + 0xf: decode OPCODE_15 { + // Normalise + 1: FailUnimpl::nrm(); + } + } // OPCODE_23_20 + } // format FloatOp + } // CPNUM + 1: decode CPNUM { // 27-24=1110,4 ==1 + 1: decode OPCODE_15_12 { + format FloatOp { 0xf: decode OPCODE_23_21 { format FloatCmp { 0x4: cmf({{ Fn.df }}, {{ Fm.df }}); @@ -417,36 +477,86 @@ format DataOp { 0x4: FailUnimpl::wfc(); 0x5: FailUnimpl::rfc(); } - } + } // format FloatOp } - } - 0xa: decode MISC_OPCODE { - 0x1: decode MEDIA_OPCODE { - 0xf: decode RN { - 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }}); - 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }}); - 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }}); - } - 0xe: decode RN { - 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }}); - 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }}); - 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }}); + 0xa: decode MISC_OPCODE { + 0x1: decode MEDIA_OPCODE { + 0xf: decode RN { + 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }}); + 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }}); + 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }}); + } + 0xe: decode RN { + 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }}); + 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }}); + 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }}); + } + } // MEDIA_OPCODE (MISC_OPCODE 0x1) + } // MISC_OPCODE (CPNUM 0xA) + 0xf: decode RN { + // Barrriers, Cache Maintence, NOPS + 7: decode OPCODE_23_21 { + 0: decode RM { + 0: decode OPC2 { + 4: decode OPCODE_20 { + 0: PredOp::mcr_cp15_nop1({{ }}); // was wfi + } + } + 1: WarnUnimpl::cp15_cache_maint(); + 4: WarnUnimpl::cp15_par(); + 5: decode OPC2 { + 0,1: WarnUnimpl::cp15_cache_maint2(); + 4: PredOp::cp15_isb({{ ; }}, IsMemBarrier, IsSerializeBefore); + 6,7: WarnUnimpl::cp15_bp_maint(); + } + 6: WarnUnimpl::cp15_cache_maint3(); + 8: WarnUnimpl::cp15_va_to_pa(); + 10: decode OPC2 { + 1,2: WarnUnimpl::cp15_cache_maint3(); + 4: PredOp::cp15_dsb({{ ; }}, IsMemBarrier, IsSerializeBefore); + 5: PredOp::cp15_dmb({{ ; }}, IsMemBarrier, IsSerializeBefore); + } + 11: WarnUnimpl::cp15_cache_maint4(); + 13: decode OPC2 { + 1: decode OPCODE_20 { + 0: PredOp::mcr_cp15_nop2({{ }}); // was prefetch + } + } + 14: WarnUnimpl::cp15_cache_maint5(); + } // RM + } // OPCODE_23_21 CR + + // Thread ID and context ID registers + // Thread ID register needs cheaper access than miscreg + 13: WarnUnimpl::mcr_mrc_cp15_c7(); + + // All the rest + default: decode OPCODE_20 { + 0: PredOp::mcr_cp15({{ + fault = setCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2); + }}); + 1: PredOp::mrc_cp15({{ + fault = readCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2); + }}); } - } + } // RN + } // CPNUM (OP4 == 1) + } //OPCODE_4 + +#if FULL_SYSTEM + 1: PredOp::swi({{ fault = new SupervisorCall; }}, IsSerializeAfter, IsNonSpeculative, IsSyscall); +#else + 1: PredOp::swi({{ if (testPredicate(CondCodes, condCode)) + { + if (IMMED_23_0) + xc->syscall(IMMED_23_0); + else + xc->syscall(R7); } - } - format PredOp { - // ARM System Call (SoftWare Interrupt) - 1: swi({{ if (testPredicate(Cpsr, condCode)) - { - if (IMMED_23_0) - xc->syscall(IMMED_23_0); - else - xc->syscall(R7); - } - }}); - } - } + }}); +#endif // FULL_SYSTEM + } // OPCODE_24 + } } diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa index 95f4f14e1..5f1b541ff 100644 --- a/src/arch/arm/isa/formats/branch.isa +++ b/src/arch/arm/isa/formats/branch.isa @@ -52,7 +52,7 @@ def format Branch(code,*opt_flags) {{ else: inst_flags += ('IsCondControl', ) - icode = 'if (testPredicate(Cpsr, condCode)) {\n' + icode = 'if (testPredicate(CondCodes, condCode)) {\n' icode += code icode += ' NPC = NPC + 4 + disp;\n' icode += '} else {\n' @@ -90,7 +90,7 @@ def format BranchExchange(code,*opt_flags) {{ #Condition code - icode = 'if (testPredicate(Cpsr, condCode)) {\n' + icode = 'if (testPredicate(CondCodes, condCode)) {\n' icode += code icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n' icode += '} else {\n' diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa index e88531580..e79529615 100644 --- a/src/arch/arm/isa/formats/fp.isa +++ b/src/arch/arm/isa/formats/fp.isa @@ -119,8 +119,8 @@ let {{ _ic = %(fReg1)s >= %(fReg2)s; _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1; - Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | - (Cpsr & 0x0FFFFFFF); + CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | + (CondCodes & 0x0FFFFFFF); ''' }}; diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 355a67ea9..c834c22cb 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -72,6 +72,18 @@ let {{ 'predicate_test': predicateTest}, ['IsMicroop']) + microLdrRetUopCode = ''' + Ra = Mem; + Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true); + ''' + microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', + 'MicroMemOp', + {'memacc_code': microLdrRetUopCode, + 'ea_code': + 'EA = Rb + (UP ? imm : -imm);', + 'predicate_test': predicateTest}, + ['IsMicroop']) + microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 'MicroMemOp', {'memacc_code': 'Mem = Ra;', @@ -80,14 +92,19 @@ let {{ ['IsMicroop']) header_output = MicroMemDeclare.subst(microLdrUopIop) + \ + MicroMemDeclare.subst(microLdrRetUopIop) + \ MicroMemDeclare.subst(microStrUopIop) decoder_output = MicroConstructor.subst(microLdrUopIop) + \ + MicroConstructor.subst(microLdrRetUopIop) + \ MicroConstructor.subst(microStrUopIop) exec_output = LoadExecute.subst(microLdrUopIop) + \ + LoadExecute.subst(microLdrRetUopIop) + \ StoreExecute.subst(microStrUopIop) + \ LoadInitiateAcc.subst(microLdrUopIop) + \ + LoadInitiateAcc.subst(microLdrRetUopIop) + \ StoreInitiateAcc.subst(microStrUopIop) + \ LoadCompleteAcc.subst(microLdrUopIop) + \ + LoadCompleteAcc.subst(microLdrRetUopIop) + \ StoreCompleteAcc.subst(microStrUopIop) }}; @@ -178,73 +195,64 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; - uint32_t regs_to_handle = reglist; - uint32_t start_addr = 0; + uint32_t regs = reglist; + uint32_t addr = 0; + bool up = machInst.puswl.up; - switch (puswl) - { - case 0x00: // stmda - case 0x01: // L ldmda_l - case 0x02: // W stmda_w - case 0x03: // WL ldmda_wl - start_addr = (ones << 2) - 4; - break; - case 0x08: // U stmia_u - case 0x09: // U L ldmia_ul - case 0x0a: // U W stmia - case 0x0b: // U WL ldmia - start_addr = 0; - break; - case 0x10: // P stmdb - case 0x11: // P L ldmdb - case 0x12: // P W stmdb - case 0x13: // P WL ldmdb - start_addr = (ones << 2); // U-bit is already 0 for subtract - break; - case 0x18: // PU stmib - case 0x19: // PU L ldmib - case 0x1a: // PU W stmib - case 0x1b: // PU WL ldmib - start_addr = 4; - break; - default: - panic("Unhandled Load/Store Multiple Instruction, " - "puswl = 0x%x", (unsigned) puswl); - break; - } + if (!up) + addr = (ones << 2) - 4; + + if (machInst.puswl.prepost) + addr += 4; - // Add 0 to Rn and stick it in Raddr (register 17). + // Add 0 to Rn and stick it in ureg0. // This is equivalent to a move. - microOps[0] = new MicroAddiUop(machInst, 17, RN, 0); + microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0); - unsigned j = 0; - for (int i = 1; i < ones+1; i++) { - // Get next available bit for transfer - while (! ( regs_to_handle & (1<<j))) - j++; - regs_to_handle &= ~(1<<j); + unsigned reg = 0; + bool force_user = machInst.puswl.psruser & !OPCODE_15; + bool exception_ret = machInst.puswl.psruser & OPCODE_15; - if (loadop) - microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr); - else - microOps[i] = new MicroStrUop(machInst, j, 17, start_addr); + for (int i = 1; i < ones + 1; i++) { + // Find the next register. + while (!bits(regs, reg)) + reg++; + replaceBits(regs, reg, 0); + + unsigned regIdx = reg; + if (force_user) { + regIdx = intRegForceUser(regIdx); + } + + if (machInst.puswl.loadOp) { + if (reg == INTREG_PC && exception_ret) { + // This must be the exception return form of ldm. + microOps[i] = + new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr); + } else { + microOps[i] = + new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr); + } + } else { + microOps[i] = + new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr); + } if (up) - start_addr += 4; + addr += 4; else - start_addr -= 4; + addr -= 4; } - if (writeback) { + StaticInstPtr &lastUop = microOps[numMicroops - 1]; + if (machInst.puswl.writeback) { if (up) { - microOps[numMicroops-1] = - new MicroAddiUop(machInst, RN, RN, ones * 4); + lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4); } else { - microOps[numMicroops-1] = - new MicroSubiUop(machInst, RN, RN, ones * 4); + lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4); } } - microOps[numMicroops-1]->setLastMicroop(); + lastUop->setLastMicroop(); } }}; @@ -285,14 +293,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) if (writeback) { if (up) { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroAddiUop(machInst, RN, RN, disp8); } else { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroSubiUop(machInst, RN, RN, disp8); } } - microOps[numMicroops-1]->setLastMicroop(); + microOps[numMicroops - 1]->setLastMicroop(); } }}; @@ -316,14 +324,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) if (writeback) { if (up) { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroAddiUop(machInst, RN, RN, disp8); } else { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroSubiUop(machInst, RN, RN, disp8); } } - microOps[numMicroops-1]->setLastMicroop(); + microOps[numMicroops - 1]->setLastMicroop(); } }}; diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa index e90788c91..0d6ee32f7 100644 --- a/src/arch/arm/isa/formats/pred.isa +++ b/src/arch/arm/isa/formats/pred.isa @@ -34,7 +34,7 @@ // let {{ - predicateTest = 'testPredicate(Cpsr, condCode)' + predicateTest = 'testPredicate(CondCodes, condCode)' }}; def template PredOpExecute {{ @@ -81,32 +81,45 @@ def template DataImmDecode {{ }}; let {{ + + calcCcCode = ''' + if (%(canOverflow)s){ + cprintf("canOverflow: %%d\\n", Rd < resTemp); + replaceBits(CondCodes, 27, Rd < resTemp); + } else { + uint16_t _ic, _iv, _iz, _in; + _in = (resTemp >> %(negBit)d) & 1; + _iz = (resTemp == 0); + _iv = %(ivValue)s & 1; + _ic = %(icValue)s & 1; + + CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | + (CondCodes & 0x0FFFFFFF); - calcCcCode = ''' - uint16_t _ic, _iv, _iz, _in; - - _in = (resTemp >> 31) & 1; - _iz = (resTemp == 0); - _iv = %(ivValue)s & 1; - _ic = %(icValue)s & 1; - - Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | - (Cpsr & 0x0FFFFFFF); - - DPRINTF(Arm, "in = %%d\\n", _in); - DPRINTF(Arm, "iz = %%d\\n", _iz); - DPRINTF(Arm, "ic = %%d\\n", _ic); - DPRINTF(Arm, "iv = %%d\\n", _iv); + DPRINTF(Arm, "in = %%d\\n", _in); + DPRINTF(Arm, "iz = %%d\\n", _iz); + DPRINTF(Arm, "ic = %%d\\n", _ic); + DPRINTF(Arm, "iv = %%d\\n", _iv); + } ''' - }}; let {{ def getCcCode(flagtype): icReg = icImm = iv = '' + negBit = 31 + canOverflow = 'false' + if flagtype == "none": - icReg = icImm = 'Cpsr<29:>' - iv = 'Cpsr<28:>' + icReg = icImm = 'CondCodes<29:>' + iv = 'CondCodes<28:>' + elif flagtype == "llbit": + icReg = icImm = 'CondCodes<29:>' + iv = 'CondCodes<28:>' + negBit = 63 + elif flagtype == "overflow": + canOverflow = "true" + icReg = icImm = iv = '0' elif flagtype == "add": icReg = icImm = 'findCarry(32, resTemp, Rn, op2)' iv = 'findOverflow(32, resTemp, Rn, op2)' @@ -117,17 +130,32 @@ let {{ icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)' iv = 'findOverflow(32, resTemp, op2, ~Rn)' else: - icReg = 'shift_carry_rs(Rm, Rs, shift, Cpsr<29:>)' - icImm = 'shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>)' - iv = 'Cpsr<28:>' - return (calcCcCode % {"icValue" : icReg, "ivValue" : iv}, - calcCcCode % {"icValue" : icImm, "ivValue" : iv}) + icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)' + icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)' + iv = 'CondCodes<28:>' + return (calcCcCode % {"icValue" : icReg, + "ivValue" : iv, + "negBit" : negBit, + "canOverflow" : canOverflow }, + calcCcCode % {"icValue" : icImm, + "ivValue" : iv, + "negBit" : negBit, + "canOverflow" : canOverflow }) def getImmCcCode(flagtype): ivValue = icValue = '' + negBit = 31 + canOverflow = 'false' if flagtype == "none": - icValue = 'Cpsr<29:>' - ivValue = 'Cpsr<28:>' + icValue = 'CondCodes<29:>' + ivValue = 'CondCodes<28:>' + elif flagtype == "llbit": + icValue = 'CondCodes<29:>' + ivValue = 'CondCodes<28:>' + negBit = 63 + elif flagtype == "overflow": + icVaule = ivValue = '0' + canOverflow = "true" elif flagtype == "add": icValue = 'findCarry(32, resTemp, Rn, rotated_imm)' ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)' @@ -138,18 +166,18 @@ let {{ icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)' ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)' else: - icValue = '(rotate ? rotated_carry:Cpsr<29:>)' - ivValue = 'Cpsr<28:>' + icValue = '(rotate ? rotated_carry:CondCodes<29:>)' + ivValue = 'CondCodes<28:>' return calcCcCode % vars() }}; def format DataOp(code, flagtype = logic) {{ (regCcCode, immCcCode) = getCcCode(flagtype) - regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs, - shift, Cpsr<29:0>); + regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>, + shift, CondCodes<29:>); op2 = op2;''' + code immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size, - shift, Cpsr<29:0>); + shift, CondCodes<29:>); op2 = op2;''' + code regIop = InstObjParams(name, Name, 'PredIntOp', {"code": regCode, diff --git a/src/arch/arm/isa/formats/unimp.isa b/src/arch/arm/isa/formats/unimp.isa index c82bb41c6..6909c3f85 100644 --- a/src/arch/arm/isa/formats/unimp.isa +++ b/src/arch/arm/isa/formats/unimp.isa @@ -115,7 +115,7 @@ output exec {{ panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE, inst2string(machInst)); - return new UnimplementedOpcodeFault; + return new UnimpFault("Unimplemented Instruction"); } Fault diff --git a/src/arch/arm/isa/formats/unknown.isa b/src/arch/arm/isa/formats/unknown.isa index 2ad7a2506..97a0caa6b 100644 --- a/src/arch/arm/isa/formats/unknown.isa +++ b/src/arch/arm/isa/formats/unknown.isa @@ -74,7 +74,7 @@ output exec {{ { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst)); - return new UnimplementedOpcodeFault; + return new UnimpFault("Unimplemented Instruction"); } }}; diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa index b5efec568..d42ffb147 100644 --- a/src/arch/arm/isa/formats/util.isa +++ b/src/arch/arm/isa/formats/util.isa @@ -33,8 +33,10 @@ let {{ # Generic substitutions for Arm instructions def ArmGenericCodeSubs(code): # Substitute in the shifted portion of operations - new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code) - new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code) + new_code = re.sub(r'Rm_Imm', + 'shift_rm_imm(Rm, shift_size, shift, CondCodes<29:>)', code) + new_code = re.sub(r'Rm_Rs', + 'shift_rm_rs(Rm, Rs, shift, CondCodes<29:>)', new_code) return new_code def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index ac7427dad..aadefc79c 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -58,15 +58,16 @@ def operands {{ 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite), 'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite), 'R7': ('IntReg', 'uw', '7', 'IsInteger', 5), + 'R0': ('IntReg', 'uw', '0', 'IsInteger', 0), #Destination register for load/store double instructions 'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite), 'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite), - 'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6), - 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7), - 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8), - 'LR': ('IntReg', 'uw', '14', 'IsInteger', 9), + 'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7), + 'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8), + 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9), + 'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', 'IsInteger', 10), #Register fields for microops 'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite), @@ -80,12 +81,13 @@ def operands {{ #Memory Operand 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30), - 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40), - 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41), - 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42), - 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43), - 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44), - 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45), - 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46) + 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', (None, None, 'IsControl'), 40), + 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', (None, None, 'IsControl'), 41), + 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', (None, None, 'IsControl'), 42), + 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', (None, None, 'IsControl'), 43), + 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', (None, None, 'IsControl'), 44), + 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', (None, None, 'IsControl'), 45), + 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50), + 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51) }}; diff --git a/src/arch/arm/isa_traits.hh b/src/arch/arm/isa_traits.hh index 542174b6b..91c51c46b 100644 --- a/src/arch/arm/isa_traits.hh +++ b/src/arch/arm/isa_traits.hh @@ -104,6 +104,8 @@ namespace ArmISA const int WordBytes = 4; const int HalfwordBytes = 2; const int ByteBytes = 1; + + const uint32_t HighVecs = 0xFFFF0000; }; using namespace ArmISA; diff --git a/src/mem/slicc/ast/TypeAST.cc b/src/arch/arm/kernel_stats.hh index 7590b4e7c..18bdc500d 100644 --- a/src/mem/slicc/ast/TypeAST.cc +++ b/src/arch/arm/kernel_stats.hh @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2004-2005 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,43 +24,34 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeAST.C - * - * Description: See TypeAST.hh - * - * $Id: TypeAST.C,v 3.1 2003/03/22 15:15:16 xu Exp $ * + * Authors: Gabe Black */ -#include "mem/slicc/ast/TypeAST.hh" +#ifndef __ARCH_ARM_KERNEL_STATS_HH__ +#define __ARCH_ARM_KERNEL_STATS_HH__ -TypeAST::TypeAST(string* ident_ptr) - : AST() -{ - m_ident_ptr = ident_ptr; -} +#include <map> +#include <stack> +#include <string> +#include <vector> -TypeAST::~TypeAST() -{ - delete m_ident_ptr; +#include "kern/kernel_stats.hh" -} +namespace ArmISA { +namespace Kernel { -string TypeAST::toString() const -{ - return *m_ident_ptr; -} +enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num }; +extern const char *modestr[]; -Type* TypeAST::lookupType() const +class Statistics : public ::Kernel::Statistics { - Type* type_ptr = g_sym_table.getType(*m_ident_ptr); - if (type_ptr != NULL) { - return type_ptr; - } else { - error("Type '" + *m_ident_ptr + "' not declared."); - } - return NULL; // Not reached -} + public: + Statistics(System *system) : ::Kernel::Statistics(system) + {} +}; + +} /* end namespace ArmISA::Kernel */ +} /* end namespace ArmISA */ + +#endif // __ARCH_ARM_KERNEL_STATS_HH__ diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index d99fa8e49..f829dd7c6 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -86,6 +86,7 @@ class ArmLinux : public Linux static const unsigned TIOCISATTY_ = 0x2000745e; static const unsigned TIOCGETS_ = 0x402c7413; static const unsigned TIOCGETA_ = 0x40127417; + static const unsigned TCSETAW_ = 0x5407; // 2.6.15 kernel //@} /// For table(). @@ -147,6 +148,21 @@ class ArmLinux : public Linux uint64_t st_ino; } tgt_stat64; + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index 56e3588a7..f909d871a 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -50,7 +50,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -179,7 +180,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = { /* 113 */ SyscallDesc("vm86", unimplementedFunc), /* 114 */ SyscallDesc("wait4", unimplementedFunc), /* 115 */ SyscallDesc("swapoff", unimplementedFunc), - /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", sysinfoFunc<ArmLinux>), /* 117 */ SyscallDesc("ipc", unimplementedFunc), /* 118 */ SyscallDesc("fsync", unimplementedFunc), /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), @@ -417,7 +418,8 @@ static SyscallReturn setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - uint32_t tlsPtr = process->getSyscallArg(tc, 0); + int index = 0; + uint32_t tlsPtr = process->getSyscallArg(tc, index); tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0, (uint8_t *)&tlsPtr, sizeof(tlsPtr)); @@ -511,12 +513,12 @@ ArmLinuxProcess::startup() } ArmISA::IntReg -ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int i) +ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int &i) { // Linux apparently allows more parameter than the ABI says it should. // This limit may need to be increased even further. assert(i < 6); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/arm/linux/process.hh b/src/arch/arm/linux/process.hh index 53b3781d2..ab836fab2 100644 --- a/src/arch/arm/linux/process.hh +++ b/src/arch/arm/linux/process.hh @@ -44,7 +44,7 @@ class ArmLinuxProcess : public ArmLiveProcess void startup(); - ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i); + ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val); /// The target system's hostname. diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 3180669de..d100efb8e 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -55,23 +55,24 @@ namespace ArmISA enum MiscRegIndex { MISCREG_CPSR = 0, - MISCREG_SPSR, + MISCREG_SPSR, MISCREG_SPSR_FIQ, MISCREG_SPSR_IRQ, MISCREG_SPSR_SVC, + MISCREG_SPSR_MON, MISCREG_SPSR_UND, MISCREG_SPSR_ABT, MISCREG_FPSR, MISCREG_FPSID, MISCREG_FPSCR, MISCREG_FPEXC, - NUM_MISCREGS + MISCREG_SCTLR, + NUM_MISCREGS }; const char * const miscRegName[NUM_MISCREGS] = { - "cpsr", - "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und", "spsr_abt", - "fpsr" + "cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und", + "spsr_abt", "fpsr", "fpsid", "fpscr", "fpexc", "sctlr" }; BitUnion32(CPSR) @@ -80,8 +81,10 @@ namespace ArmISA Bitfield<29> c; Bitfield<28> v; Bitfield<27> q; + Bitfield<26,25> it1; Bitfield<24> j; Bitfield<19, 16> ge; + Bitfield<15,10> it2; Bitfield<9> e; Bitfield<8> a; Bitfield<7> i; @@ -89,6 +92,35 @@ namespace ArmISA Bitfield<5> t; Bitfield<4, 0> mode; EndBitUnion(CPSR) + + // This mask selects bits of the CPSR that actually go in the CondCodes + // integer register to allow renaming. + static const uint32_t CondCodesMask = 0xF80F0000; + + BitUnion32(SCTLR) + Bitfield<30> te; // Thumb Exception Enable + Bitfield<29> afe; // Access flag enable + Bitfield<28> tre; // TEX Remap bit + Bitfield<27> nmfi;// Non-maskable fast interrupts enable + Bitfield<25> ee; // Exception Endianness bit + Bitfield<24> ve; // Interrupt vectors enable + Bitfield<23> rao1;// Read as one + Bitfield<22> u; // Alignment (now unused) + Bitfield<21> fi; // Fast interrupts configuration enable + Bitfield<18> rao2;// Read as one + Bitfield<17> ha; // Hardware access flag enable + Bitfield<16> rao3;// Read as one + Bitfield<14> rr; // Round robin cache replacement + Bitfield<13> v; // Base address for exception vectors + Bitfield<12> i; // instruction cache enable + Bitfield<11> z; // branch prediction enable bit + Bitfield<10> sw; // Enable swp/swpb + Bitfield<6,3> rao4;// Read as one + Bitfield<7> b; // Endianness support (unused) + Bitfield<2> c; // Cache enable bit + Bitfield<1> a; // Alignment fault checking + Bitfield<0> m; // MMU enable bit + EndBitUnion(SCTLR) }; #endif // __ARCH_ARM_MISCREGS_HH__ diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 1ad9e1a19..01f3205eb 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -97,7 +97,8 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc) changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]); //CPSR - newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR); + newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) | + tc->readIntReg(INTREG_CONDCODES); changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]); } diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc index cd7cc9736..702922a43 100644 --- a/src/arch/arm/process.cc +++ b/src/arch/arm/process.cc @@ -324,10 +324,10 @@ ArmLiveProcess::argsInit(int intSize, int pageSize) } ArmISA::IntReg -ArmLiveProcess::getSyscallArg(ThreadContext *tc, int i) +ArmLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 4); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/arm/process.hh b/src/arch/arm/process.hh index 8954d3719..f793892d0 100644 --- a/src/arch/arm/process.hh +++ b/src/arch/arm/process.hh @@ -53,7 +53,7 @@ class ArmLiveProcess : public LiveProcess public: void argsInit(int intSize, int pageSize); - ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i); + ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 7f9b6b828..41bbf4e7f 100644 --- a/src/arch/arm/registers.hh +++ b/src/arch/arm/registers.hh @@ -32,6 +32,7 @@ #define __ARCH_ARM_REGISTERS_HH__ #include "arch/arm/max_inst_regs.hh" +#include "arch/arm/intregs.hh" #include "arch/arm/miscregs.hh" namespace ArmISA { @@ -51,13 +52,11 @@ typedef float FloatReg; typedef uint64_t MiscReg; // Constants Related to the number of registers -const int NumIntArchRegs = 16; -const int NumIntSpecialRegs = 19; +const int NumIntArchRegs = NUM_ARCH_INTREGS; const int NumFloatArchRegs = 16; const int NumFloatSpecialRegs = 5; -const int NumInternalProcRegs = 0; -const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; +const int NumIntRegs = NUM_INTREGS; const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs; const int NumMiscRegs = NUM_MISCREGS; @@ -72,12 +71,11 @@ const int ArgumentReg1 = 1; const int ArgumentReg2 = 2; const int ArgumentReg3 = 3; const int FramePointerReg = 11; -const int StackPointerReg = 13; -const int ReturnAddressReg = 14; -const int PCReg = 15; +const int StackPointerReg = INTREG_SP; +const int ReturnAddressReg = INTREG_LR; +const int PCReg = INTREG_PC; -const int ZeroReg = NumIntArchRegs; -const int AddrReg = ZeroReg + 1; // Used to generate address for uops +const int ZeroReg = INTREG_ZERO; const int SyscallNumReg = ReturnValueReg; const int SyscallPseudoReturnReg = ReturnValueReg; @@ -116,35 +114,6 @@ enum FCSRFields { Cause_Field = 11 }; -enum MiscIntRegNums { - zero_reg = NumIntArchRegs, - addr_reg, - - rhi, - rlo, - - r8_fiq, /* FIQ mode register bank */ - r9_fiq, - r10_fiq, - r11_fiq, - r12_fiq, - - r13_fiq, /* FIQ mode SP and LR */ - r14_fiq, - - r13_irq, /* IRQ mode SP and LR */ - r14_irq, - - r13_svc, /* SVC mode SP and LR */ - r14_svc, - - r13_undef, /* UNDEF mode SP and LR */ - r14_undef, - - r13_abt, /* ABT mode SP and LR */ - r14_abt -}; - } // namespace ArmISA #endif diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc new file mode 100644 index 000000000..6b346b0ab --- /dev/null +++ b/src/arch/arm/stacktrace.cc @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#include <string> + +#include "arch/arm/isa_traits.hh" +#include "arch/arm/stacktrace.hh" +#include "arch/arm/vtophys.hh" +#include "base/bitfield.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" +#include "sim/system.hh" + +using namespace std; +namespace ArmISA +{ + ProcessInfo::ProcessInfo(ThreadContext *_tc) + : tc(_tc) + { + Addr addr = 0; + + VirtualPort *vp; + + vp = tc->getVirtPort(); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) + panic("thread info not compiled into kernel\n"); + thread_info_size = vp->readGtoH<int32_t>(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) + panic("thread info not compiled into kernel\n"); + task_struct_size = vp->readGtoH<int32_t>(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) + panic("thread info not compiled into kernel\n"); + task_off = vp->readGtoH<int32_t>(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) + panic("thread info not compiled into kernel\n"); + pid_off = vp->readGtoH<int32_t>(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) + panic("thread info not compiled into kernel\n"); + name_off = vp->readGtoH<int32_t>(addr); + } + + Addr + ProcessInfo::task(Addr ksp) const + { + return 0; + } + + int + ProcessInfo::pid(Addr ksp) const + { + return -1; + } + + string + ProcessInfo::name(Addr ksp) const + { + return "Implement me"; + } + + StackTrace::StackTrace() + : tc(0), stack(64) + { + } + + StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) + : tc(0), stack(64) + { + trace(_tc, inst); + } + + StackTrace::~StackTrace() + { + } + + void + StackTrace::trace(ThreadContext *_tc, bool is_call) + { + } + + bool + StackTrace::isEntry(Addr addr) + { + return false; + } + + bool + StackTrace::decodeStack(MachInst inst, int &disp) + { + return false; + } + + bool + StackTrace::decodeSave(MachInst inst, int ®, int &disp) + { + return false; + } + + /* + * Decode the function prologue for the function we're in, and note + * which registers are stored where, and how large the stack frame is. + */ + bool + StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, + int &size, Addr &ra) + { + return false; + } + +#if TRACING_ON + void + StackTrace::dump() + { + DPRINTFN("------ Stack ------\n"); + + DPRINTFN(" Not implemented\n"); + } +#endif +} diff --git a/src/arch/arm/stacktrace.hh b/src/arch/arm/stacktrace.hh index 3f9c91096..05fdb9e78 100644 --- a/src/arch/arm/stacktrace.hh +++ b/src/arch/arm/stacktrace.hh @@ -1,6 +1,5 @@ /* * Copyright (c) 2005 The Regents of The University of Michigan - * Copyright (c) 2007-2008 The Florida State University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,8 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Ali Saidi - * Stephen Hines + * Authors: Nathan Binkert */ #ifndef __ARCH_ARM_STACKTRACE_HH__ @@ -37,11 +35,11 @@ #include "cpu/static_inst.hh" class ThreadContext; -class StackTrace; - namespace ArmISA { +class StackTrace; + class ProcessInfo { private: @@ -64,7 +62,7 @@ class ProcessInfo class StackTrace { protected: - typedef TheISA::MachInst MachInst; + typedef ArmISA::MachInst MachInst; private: ThreadContext *tc; std::vector<Addr> stack; @@ -94,10 +92,6 @@ class StackTrace public: const std::vector<Addr> &getstack() const { return stack; } - static const int user = 1; - static const int console = 2; - static const int unknown = 3; - #if TRACING_ON private: void dump(); @@ -123,6 +117,6 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) return true; } -} +} // Namespace ArmISA #endif // __ARCH_ARM_STACKTRACE_HH__ diff --git a/src/mem/slicc/ast/TypeFieldAST.cc b/src/arch/arm/system.cc index 5657d023c..e7470f89a 100644 --- a/src/mem/slicc/ast/TypeFieldAST.cc +++ b/src/arch/arm/system.cc @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2002-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,20 +24,28 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldAST.C - * - * Description: See TypeFieldAST.hh - * - * $Id$ * + * Authors: Ali Saidi */ -#include "mem/slicc/ast/TypeFieldAST.hh" +#include "arch/arm/system.hh" + -TypeFieldAST::TypeFieldAST(PairListAST* pairs_ptr) - : AST(pairs_ptr->getPairs()) { +using namespace LittleEndianGuest; + +ArmSystem::ArmSystem(Params *p) + : System(p) +{ + +} + +ArmSystem::~ArmSystem() +{ } + +ArmSystem * +ArmSystemParams::create() +{ + return new ArmSystem(this); +} diff --git a/src/mem/slicc/ast/StatementAST.cc b/src/arch/arm/system.hh index 35627722a..9dfb66fb7 100644 --- a/src/mem/slicc/ast/StatementAST.cc +++ b/src/arch/arm/system.hh @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2002-2005 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,36 +24,33 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * StatementAST.C - * - * Description: See StatementAST.hh - * - * $Id$ * + * Authors: Ali Saidi */ -#include "mem/slicc/ast/StatementAST.hh" +#ifndef __ARCH_ARM_SYSTEM_HH__ +#define __ARCH_ARM_SYSTEM_HH__ -static int indentation_depth = 1; +#include <string> +#include <vector> -void inc_indent() -{ - indentation_depth++; -} +#include "params/ArmSystem.hh" +#include "sim/sim_object.hh" +#include "sim/system.hh" -void dec_indent() +class ArmSystem : public System { - indentation_depth--; -} + public: + typedef ArmSystemParams Params; + ArmSystem(Params *p); + ~ArmSystem(); + + virtual Addr fixFuncEventAddr(Addr addr) + { + //XXX This may eventually have to do something useful. + return addr; + } +}; + +#endif -string indent_str() -{ - string temp; - for(int i=0; i<indentation_depth; i++) { - temp += " "; - } - return temp; -} diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index febc6d081..864c061a2 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -287,7 +287,15 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) return NoFault; #else - fatal("translate atomic not yet implemented\n"); + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + if (!sctlr.m) { + req->setPaddr(req->getVaddr()); + return NoFault; + } + panic("MMU translation not implemented\n"); + return NoFault; + + #endif } diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 2c4e1291c..e0b3951b9 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -45,16 +45,20 @@ namespace ArmISA // All the different types of opcode fields. Bitfield<27, 25> encoding; + Bitfield<25> useImm; Bitfield<24, 21> opcode; Bitfield<24, 20> mediaOpcode; Bitfield<24> opcode24; Bitfield<23, 20> opcode23_20; Bitfield<23, 21> opcode23_21; + Bitfield<20> opcode20; Bitfield<22> opcode22; Bitfield<19> opcode19; + Bitfield<18> opcode18; Bitfield<15, 12> opcode15_12; Bitfield<15> opcode15; Bitfield<7, 4> miscOpcode; + Bitfield<7,5> opc2; Bitfield<7> opcode7; Bitfield<4> opcode4; @@ -156,6 +160,7 @@ namespace ArmISA MODE_FIQ = 17, MODE_IRQ = 18, MODE_SVC = 19, + MODE_MON = 22, MODE_ABORT = 23, MODE_UNDEFINED = 27, MODE_SYSTEM = 31 diff --git a/src/mem/slicc/ast/ExprStatementAST.cc b/src/arch/arm/utility.cc index f4bffaab3..5ce32542b 100644 --- a/src/mem/slicc/ast/ExprStatementAST.cc +++ b/src/arch/arm/utility.cc @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 ARM Limited * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,49 +24,53 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ExprStatementAST.C - * - * Description: See ExprStatementAST.hh - * - * $Id$ * + * Authors: Ali Saidi */ -#include "mem/slicc/ast/ExprStatementAST.hh" -ExprStatementAST::ExprStatementAST(ExprAST* expr_ptr) - : StatementAST() +#include "arch/arm/faults.hh" +#include "arch/arm/utility.hh" +#include "cpu/thread_context.hh" + + +namespace ArmISA { + +void +initCPU(ThreadContext *tc, int cpuId) { - m_expr_ptr = expr_ptr; + // Reset CP15?? What does that mean -- ali + + // FPEXC.EN = 0 + + static Fault reset = new Reset; + if (cpuId == 0) + reset->invoke(tc); } -ExprStatementAST::~ExprStatementAST() -{ - delete m_expr_ptr; +uint64_t getArgument(ThreadContext *tc, int number, bool fp) { +#if FULL_SYSTEM + panic("getArgument() not implemented for ARM!\n"); +#else + panic("getArgument() only implemented for FULL_SYSTEM\n"); + M5_DUMMY_RETURN +#endif } -void ExprStatementAST::generate(string& code, Type* return_type_ptr) const +Fault +setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2) { - code += indent_str(); - Type* actual_type_ptr = m_expr_ptr->generate(code); - code += ";\n"; - - // The return type must be void - Type* expected_type_ptr = g_sym_table.getType("void"); - if (expected_type_ptr != actual_type_ptr) { - m_expr_ptr->error("Non-void return must not be ignored, return type is '" + actual_type_ptr->toString() + "'"); - } + return new UnimpFault(csprintf("MCR CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n", + CRn, opc1, CRm, opc2)); } -void ExprStatementAST::findResources(Map<Var*, string>& resource_list) const +Fault +readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2) { - m_expr_ptr->findResources(resource_list); + return new UnimpFault(csprintf("MRC CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n", + CRn, opc1, CRm, opc2)); + } -void ExprStatementAST::print(ostream& out) const -{ - out << "[ExprStatementAST: " << *m_expr_ptr << "]"; + } diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index a2f0ef170..3ddfd12dd 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -125,6 +125,20 @@ namespace ArmISA { { panic("Copy Misc. Regs Not Implemented Yet\n"); } + + void initCPU(ThreadContext *tc, int cpuId); + + static inline bool + inUserMode(ThreadContext *tc) + { + return (tc->readMiscRegNoEffect(MISCREG_CPSR) & 0x1f) == MODE_USER; + } + +uint64_t getArgument(ThreadContext *tc, int number, bool fp); + +Fault setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2); +Fault readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2); + }; diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index d5b5bbe4f..2db7c6aa6 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -34,702 +34,704 @@ import traceback # get type names from types import * -# Prepend the directory where the PLY lex & yacc modules are found -# to the search path. Assumes we're compiling in a subdirectory -# of 'build' in the current tree. -sys.path[0:0] = [os.environ['M5_PLY']] - -from ply import lex -from ply import yacc - -##################################################################### -# -# Lexer -# -# The PLY lexer module takes two things as input: -# - A list of token names (the string list 'tokens') -# - A regular expression describing a match for each token. The -# regexp for token FOO can be provided in two ways: -# - as a string variable named t_FOO -# - as the doc string for a function named t_FOO. In this case, -# the function is also executed, allowing an action to be -# associated with each token match. -# -##################################################################### - -# Reserved words. These are listed separately as they are matched -# using the same regexp as generic IDs, but distinguished in the -# t_ID() function. The PLY documentation suggests this approach. -reserved = ( - 'BITFIELD', 'DECODE', 'DECODER', 'DEFAULT', 'DEF', 'EXEC', 'FORMAT', - 'HEADER', 'LET', 'NAMESPACE', 'OPERAND_TYPES', 'OPERANDS', - 'OUTPUT', 'SIGNED', 'TEMPLATE' +from m5.util.grammar import Grammar + +class ISAParser(Grammar): + def __init__(self, *args, **kwargs): + super(ISAParser, self).__init__(*args, **kwargs) + self.templateMap = {} + + ##################################################################### + # + # Lexer + # + # The PLY lexer module takes two things as input: + # - A list of token names (the string list 'tokens') + # - A regular expression describing a match for each token. The + # regexp for token FOO can be provided in two ways: + # - as a string variable named t_FOO + # - as the doc string for a function named t_FOO. In this case, + # the function is also executed, allowing an action to be + # associated with each token match. + # + ##################################################################### + + # Reserved words. These are listed separately as they are matched + # using the same regexp as generic IDs, but distinguished in the + # t_ID() function. The PLY documentation suggests this approach. + reserved = ( + 'BITFIELD', 'DECODE', 'DECODER', 'DEFAULT', 'DEF', 'EXEC', 'FORMAT', + 'HEADER', 'LET', 'NAMESPACE', 'OPERAND_TYPES', 'OPERANDS', + 'OUTPUT', 'SIGNED', 'TEMPLATE' + ) + + # List of tokens. The lex module requires this. + tokens = reserved + ( + # identifier + 'ID', + + # integer literal + 'INTLIT', + + # string literal + 'STRLIT', + + # code literal + 'CODELIT', + + # ( ) [ ] { } < > , ; . : :: * + 'LPAREN', 'RPAREN', + 'LBRACKET', 'RBRACKET', + 'LBRACE', 'RBRACE', + 'LESS', 'GREATER', 'EQUALS', + 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON', + 'ASTERISK', + + # C preprocessor directives + 'CPPDIRECTIVE' + + # The following are matched but never returned. commented out to + # suppress PLY warning + # newfile directive + # 'NEWFILE', + + # endfile directive + # 'ENDFILE' ) -# List of tokens. The lex module requires this. -tokens = reserved + ( - # identifier - 'ID', - - # integer literal - 'INTLIT', - - # string literal - 'STRLIT', - - # code literal - 'CODELIT', - - # ( ) [ ] { } < > , ; . : :: * - 'LPAREN', 'RPAREN', - 'LBRACKET', 'RBRACKET', - 'LBRACE', 'RBRACE', - 'LESS', 'GREATER', 'EQUALS', - 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON', - 'ASTERISK', - - # C preprocessor directives - 'CPPDIRECTIVE' - -# The following are matched but never returned. commented out to -# suppress PLY warning - # newfile directive -# 'NEWFILE', - - # endfile directive -# 'ENDFILE' -) - -# Regular expressions for token matching -t_LPAREN = r'\(' -t_RPAREN = r'\)' -t_LBRACKET = r'\[' -t_RBRACKET = r'\]' -t_LBRACE = r'\{' -t_RBRACE = r'\}' -t_LESS = r'\<' -t_GREATER = r'\>' -t_EQUALS = r'=' -t_COMMA = r',' -t_SEMI = r';' -t_DOT = r'\.' -t_COLON = r':' -t_DBLCOLON = r'::' -t_ASTERISK = r'\*' - -# Identifiers and reserved words -reserved_map = { } -for r in reserved: - reserved_map[r.lower()] = r - -def t_ID(t): - r'[A-Za-z_]\w*' - t.type = reserved_map.get(t.value,'ID') - return t - -# Integer literal -def t_INTLIT(t): - r'(0x[\da-fA-F]+)|\d+' - try: - t.value = int(t.value,0) - except ValueError: - error(t.lexer.lineno, 'Integer value "%s" too large' % t.value) - t.value = 0 - return t - -# String literal. Note that these use only single quotes, and -# can span multiple lines. -def t_STRLIT(t): - r"(?m)'([^'])+'" - # strip off quotes - t.value = t.value[1:-1] - t.lexer.lineno += t.value.count('\n') - return t - - -# "Code literal"... like a string literal, but delimiters are -# '{{' and '}}' so they get formatted nicely under emacs c-mode -def t_CODELIT(t): - r"(?m)\{\{([^\}]|}(?!\}))+\}\}" - # strip off {{ & }} - t.value = t.value[2:-2] - t.lexer.lineno += t.value.count('\n') - return t - -def t_CPPDIRECTIVE(t): - r'^\#[^\#].*\n' - t.lexer.lineno += t.value.count('\n') - return t - -def t_NEWFILE(t): - r'^\#\#newfile\s+"[\w/.-]*"' - fileNameStack.push((t.value[11:-1], t.lexer.lineno)) - t.lexer.lineno = 0 - -def t_ENDFILE(t): - r'^\#\#endfile' - (old_filename, t.lexer.lineno) = fileNameStack.pop() - -# -# The functions t_NEWLINE, t_ignore, and t_error are -# special for the lex module. -# - -# Newlines -def t_NEWLINE(t): - r'\n+' - t.lexer.lineno += t.value.count('\n') - -# Comments -def t_comment(t): - r'//.*' - -# Completely ignored characters -t_ignore = ' \t\x0c' - -# Error handler -def t_error(t): - error(t.lexer.lineno, "illegal character '%s'" % t.value[0]) - t.skip(1) - -# Build the lexer -lexer = lex.lex() - -##################################################################### -# -# Parser -# -# Every function whose name starts with 'p_' defines a grammar rule. -# The rule is encoded in the function's doc string, while the -# function body provides the action taken when the rule is matched. -# The argument to each function is a list of the values of the -# rule's symbols: t[0] for the LHS, and t[1..n] for the symbols -# on the RHS. For tokens, the value is copied from the t.value -# attribute provided by the lexer. For non-terminals, the value -# is assigned by the producing rule; i.e., the job of the grammar -# rule function is to set the value for the non-terminal on the LHS -# (by assigning to t[0]). -##################################################################### - -# The LHS of the first grammar rule is used as the start symbol -# (in this case, 'specification'). Note that this rule enforces -# that there will be exactly one namespace declaration, with 0 or more -# global defs/decls before and after it. The defs & decls before -# the namespace decl will be outside the namespace; those after -# will be inside. The decoder function is always inside the namespace. -def p_specification(t): - 'specification : opt_defs_and_outputs name_decl opt_defs_and_outputs decode_block' - global_code = t[1] - isa_name = t[2] - namespace = isa_name + "Inst" - # wrap the decode block as a function definition - t[4].wrap_decode_block(''' + # Regular expressions for token matching + t_LPAREN = r'\(' + t_RPAREN = r'\)' + t_LBRACKET = r'\[' + t_RBRACKET = r'\]' + t_LBRACE = r'\{' + t_RBRACE = r'\}' + t_LESS = r'\<' + t_GREATER = r'\>' + t_EQUALS = r'=' + t_COMMA = r',' + t_SEMI = r';' + t_DOT = r'\.' + t_COLON = r':' + t_DBLCOLON = r'::' + t_ASTERISK = r'\*' + + # Identifiers and reserved words + reserved_map = { } + for r in reserved: + reserved_map[r.lower()] = r + + def t_ID(self, t): + r'[A-Za-z_]\w*' + t.type = self.reserved_map.get(t.value, 'ID') + return t + + # Integer literal + def t_INTLIT(self, t): + r'(0x[\da-fA-F]+)|\d+' + try: + t.value = int(t.value,0) + except ValueError: + error(t.lexer.lineno, 'Integer value "%s" too large' % t.value) + t.value = 0 + return t + + # String literal. Note that these use only single quotes, and + # can span multiple lines. + def t_STRLIT(self, t): + r"(?m)'([^'])+'" + # strip off quotes + t.value = t.value[1:-1] + t.lexer.lineno += t.value.count('\n') + return t + + + # "Code literal"... like a string literal, but delimiters are + # '{{' and '}}' so they get formatted nicely under emacs c-mode + def t_CODELIT(self, t): + r"(?m)\{\{([^\}]|}(?!\}))+\}\}" + # strip off {{ & }} + t.value = t.value[2:-2] + t.lexer.lineno += t.value.count('\n') + return t + + def t_CPPDIRECTIVE(self, t): + r'^\#[^\#].*\n' + t.lexer.lineno += t.value.count('\n') + return t + + def t_NEWFILE(self, t): + r'^\#\#newfile\s+"[\w/.-]*"' + fileNameStack.push((t.value[11:-1], t.lexer.lineno)) + t.lexer.lineno = 0 + + def t_ENDFILE(self, t): + r'^\#\#endfile' + (old_filename, t.lexer.lineno) = fileNameStack.pop() + + # + # The functions t_NEWLINE, t_ignore, and t_error are + # special for the lex module. + # + + # Newlines + def t_NEWLINE(self, t): + r'\n+' + t.lexer.lineno += t.value.count('\n') + + # Comments + def t_comment(self, t): + r'//.*' + + # Completely ignored characters + t_ignore = ' \t\x0c' + + # Error handler + def t_error(self, t): + error(t.lexer.lineno, "illegal character '%s'" % t.value[0]) + t.skip(1) + + ##################################################################### + # + # Parser + # + # Every function whose name starts with 'p_' defines a grammar + # rule. The rule is encoded in the function's doc string, while + # the function body provides the action taken when the rule is + # matched. The argument to each function is a list of the values + # of the rule's symbols: t[0] for the LHS, and t[1..n] for the + # symbols on the RHS. For tokens, the value is copied from the + # t.value attribute provided by the lexer. For non-terminals, the + # value is assigned by the producing rule; i.e., the job of the + # grammar rule function is to set the value for the non-terminal + # on the LHS (by assigning to t[0]). + ##################################################################### + + # The LHS of the first grammar rule is used as the start symbol + # (in this case, 'specification'). Note that this rule enforces + # that there will be exactly one namespace declaration, with 0 or + # more global defs/decls before and after it. The defs & decls + # before the namespace decl will be outside the namespace; those + # after will be inside. The decoder function is always inside the + # namespace. + def p_specification(self, t): + 'specification : opt_defs_and_outputs name_decl opt_defs_and_outputs decode_block' + global_code = t[1] + isa_name = t[2] + namespace = isa_name + "Inst" + # wrap the decode block as a function definition + t[4].wrap_decode_block(''' StaticInstPtr %(isa_name)s::decodeInst(%(isa_name)s::ExtMachInst machInst) { using namespace %(namespace)s; ''' % vars(), '}') - # both the latter output blocks and the decode block are in the namespace - namespace_code = t[3] + t[4] - # pass it all back to the caller of yacc.parse() - t[0] = (isa_name, namespace, global_code, namespace_code) - -# ISA name declaration looks like "namespace <foo>;" -def p_name_decl(t): - 'name_decl : NAMESPACE ID SEMI' - t[0] = t[2] - -# 'opt_defs_and_outputs' is a possibly empty sequence of -# def and/or output statements. -def p_opt_defs_and_outputs_0(t): - 'opt_defs_and_outputs : empty' - t[0] = GenCode() - -def p_opt_defs_and_outputs_1(t): - 'opt_defs_and_outputs : defs_and_outputs' - t[0] = t[1] - -def p_defs_and_outputs_0(t): - 'defs_and_outputs : def_or_output' - t[0] = t[1] - -def p_defs_and_outputs_1(t): - 'defs_and_outputs : defs_and_outputs def_or_output' - t[0] = t[1] + t[2] - -# The list of possible definition/output statements. -def p_def_or_output(t): - '''def_or_output : def_format - | def_bitfield - | def_bitfield_struct - | def_template - | def_operand_types - | def_operands - | output_header - | output_decoder - | output_exec - | global_let''' - t[0] = t[1] - -# Output blocks 'output <foo> {{...}}' (C++ code blocks) are copied -# directly to the appropriate output section. - - -# Protect any non-dict-substitution '%'s in a format string -# (i.e. those not followed by '(') -def protect_non_subst_percents(s): - return re.sub(r'%(?!\()', '%%', s) - -# 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 format -# operation will reduce them back to single '%'s. -def process_output(s): - s = protect_non_subst_percents(s) - # protects cpu-specific symbols too - s = protect_cpu_symbols(s) - return substBitOps(s % templateMap) - -def p_output_header(t): - 'output_header : OUTPUT HEADER CODELIT SEMI' - t[0] = GenCode(header_output = process_output(t[3])) - -def p_output_decoder(t): - 'output_decoder : OUTPUT DECODER CODELIT SEMI' - t[0] = GenCode(decoder_output = process_output(t[3])) - -def p_output_exec(t): - 'output_exec : OUTPUT EXEC CODELIT SEMI' - t[0] = GenCode(exec_output = process_output(t[3])) - -# global let blocks 'let {{...}}' (Python code blocks) are executed -# directly when seen. Note that these execute in a special variable -# context 'exportContext' to prevent the code from polluting this -# script's namespace. -def p_global_let(t): - 'global_let : LET CODELIT SEMI' - updateExportContext() - exportContext["header_output"] = '' - exportContext["decoder_output"] = '' - exportContext["exec_output"] = '' - exportContext["decode_block"] = '' - try: - exec fixPythonIndentation(t[2]) in exportContext - except Exception, exc: - error(t.lexer.lineno, - 'error: %s in global let block "%s".' % (exc, t[2])) - t[0] = GenCode(header_output = exportContext["header_output"], - decoder_output = exportContext["decoder_output"], - exec_output = exportContext["exec_output"], - decode_block = exportContext["decode_block"]) - -# Define the mapping from operand type extensions to C++ types and bit -# widths (stored in operandTypeMap). -def p_def_operand_types(t): - 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI' - try: - userDict = eval('{' + t[3] + '}') - except Exception, exc: - error(t.lexer.lineno, - 'error: %s in def operand_types block "%s".' % (exc, t[3])) - buildOperandTypeMap(userDict, t.lexer.lineno) - t[0] = GenCode() # contributes nothing to the output C++ file - -# Define the mapping from operand names to operand classes and other -# traits. Stored in operandNameMap. -def p_def_operands(t): - 'def_operands : DEF OPERANDS CODELIT SEMI' - if not globals().has_key('operandTypeMap'): - error(t.lexer.lineno, - 'error: operand types must be defined before operands') - try: - userDict = eval('{' + t[3] + '}', exportContext) - except Exception, exc: - error(t.lexer.lineno, - 'error: %s in def operands block "%s".' % (exc, t[3])) - buildOperandNameMap(userDict, t.lexer.lineno) - t[0] = GenCode() # contributes nothing to the output C++ file - -# A bitfield definition looks like: -# 'def [signed] bitfield <ID> [<first>:<last>]' -# This generates a preprocessor macro in the output file. -def p_def_bitfield_0(t): - 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI' - expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8]) - if (t[2] == 'signed'): - expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr) - hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) - t[0] = GenCode(header_output = hash_define) - -# alternate form for single bit: 'def [signed] bitfield <ID> [<bit>]' -def p_def_bitfield_1(t): - 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI' - expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6]) - if (t[2] == 'signed'): - expr = 'sext<%d>(%s)' % (1, expr) - hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) - t[0] = GenCode(header_output = hash_define) - -# alternate form for structure member: 'def bitfield <ID> <ID>' -def p_def_bitfield_struct(t): - 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI' - if (t[2] != ''): - error(t.lexer.lineno, 'error: structure bitfields are always unsigned.') - expr = 'machInst.%s' % t[5] - hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) - t[0] = GenCode(header_output = hash_define) - -def p_id_with_dot_0(t): - 'id_with_dot : ID' - t[0] = t[1] - -def p_id_with_dot_1(t): - 'id_with_dot : ID DOT id_with_dot' - t[0] = t[1] + t[2] + t[3] - -def p_opt_signed_0(t): - 'opt_signed : SIGNED' - t[0] = t[1] - -def p_opt_signed_1(t): - 'opt_signed : empty' - t[0] = '' - -# Global map variable to hold templates -templateMap = {} - -def p_def_template(t): - 'def_template : DEF TEMPLATE ID CODELIT SEMI' - templateMap[t[3]] = Template(t[4]) - t[0] = GenCode() - -# An instruction format definition looks like -# "def format <fmt>(<params>) {{...}};" -def p_def_format(t): - 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI' - (id, params, code) = (t[3], t[5], t[7]) - defFormat(id, params, code, t.lexer.lineno) - t[0] = GenCode() - -# The formal parameter list for an instruction format is a possibly -# empty list of comma-separated parameters. Positional (standard, -# non-keyword) parameters must come first, followed by keyword -# parameters, followed by a '*foo' parameter that gets excess -# positional arguments (as in Python). Each of these three parameter -# categories is optional. -# -# Note that we do not support the '**foo' parameter for collecting -# otherwise undefined keyword args. Otherwise the parameter list is -# (I believe) identical to what is supported in Python. -# -# The param list generates a tuple, where the first element is a list of -# the positional params and the second element is a dict containing the -# keyword params. -def p_param_list_0(t): - 'param_list : positional_param_list COMMA nonpositional_param_list' - t[0] = t[1] + t[3] - -def p_param_list_1(t): - '''param_list : positional_param_list - | nonpositional_param_list''' - t[0] = t[1] - -def p_positional_param_list_0(t): - 'positional_param_list : empty' - t[0] = [] - -def p_positional_param_list_1(t): - 'positional_param_list : ID' - t[0] = [t[1]] - -def p_positional_param_list_2(t): - 'positional_param_list : positional_param_list COMMA ID' - t[0] = t[1] + [t[3]] - -def p_nonpositional_param_list_0(t): - 'nonpositional_param_list : keyword_param_list COMMA excess_args_param' - t[0] = t[1] + t[3] - -def p_nonpositional_param_list_1(t): - '''nonpositional_param_list : keyword_param_list - | excess_args_param''' - t[0] = t[1] - -def p_keyword_param_list_0(t): - 'keyword_param_list : keyword_param' - t[0] = [t[1]] - -def p_keyword_param_list_1(t): - 'keyword_param_list : keyword_param_list COMMA keyword_param' - t[0] = t[1] + [t[3]] - -def p_keyword_param(t): - 'keyword_param : ID EQUALS expr' - t[0] = t[1] + ' = ' + t[3].__repr__() - -def p_excess_args_param(t): - 'excess_args_param : ASTERISK ID' - # Just concatenate them: '*ID'. Wrap in list to be consistent - # with positional_param_list and keyword_param_list. - t[0] = [t[1] + t[2]] - -# End of format definition-related rules. -############## - -# -# A decode block looks like: -# decode <field1> [, <field2>]* [default <inst>] { ... } -# -def p_decode_block(t): - 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE' - default_defaults = defaultStack.pop() - codeObj = t[5] - # use the "default defaults" only if there was no explicit - # default statement in decode_stmt_list - if not codeObj.has_decode_default: - codeObj += default_defaults - codeObj.wrap_decode_block('switch (%s) {\n' % t[2], '}\n') - t[0] = codeObj - -# The opt_default statement serves only to push the "default defaults" -# onto defaultStack. This value will be used by nested decode blocks, -# and used and popped off when the current decode_block is processed -# (in p_decode_block() above). -def p_opt_default_0(t): - 'opt_default : empty' - # no default specified: reuse the one currently at the top of the stack - defaultStack.push(defaultStack.top()) - # no meaningful value returned - t[0] = None - -def p_opt_default_1(t): - 'opt_default : DEFAULT inst' - # push the new default - codeObj = t[2] - codeObj.wrap_decode_block('\ndefault:\n', 'break;\n') - defaultStack.push(codeObj) - # no meaningful value returned - t[0] = None - -def p_decode_stmt_list_0(t): - 'decode_stmt_list : decode_stmt' - t[0] = t[1] - -def p_decode_stmt_list_1(t): - 'decode_stmt_list : decode_stmt decode_stmt_list' - if (t[1].has_decode_default and t[2].has_decode_default): - error(t.lexer.lineno, 'Two default cases in decode block') - t[0] = t[1] + t[2] - -# -# Decode statement rules -# -# There are four types of statements allowed in a decode block: -# 1. Format blocks 'format <foo> { ... }' -# 2. Nested decode blocks -# 3. Instruction definitions. -# 4. C preprocessor directives. - - -# Preprocessor directives found in a decode statement list are passed -# through to the output, replicated to all of the output code -# streams. This works well for ifdefs, so we can ifdef out both the -# declarations and the decode cases generated by an instruction -# definition. Handling them as part of the grammar makes it easy to -# keep them in the right place with respect to the code generated by -# the other statements. -def p_decode_stmt_cpp(t): - 'decode_stmt : CPPDIRECTIVE' - t[0] = GenCode(t[1], t[1], t[1], t[1]) - -# A format block 'format <foo> { ... }' sets the default instruction -# format used to handle instruction definitions inside the block. -# This format can be overridden by using an explicit format on the -# instruction definition or with a nested format block. -def p_decode_stmt_format(t): - 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE' - # The format will be pushed on the stack when 'push_format_id' is - # processed (see below). Once the parser has recognized the full - # production (though the right brace), we're done with the format, - # so now we can pop it. - formatStack.pop() - t[0] = t[4] - -# This rule exists so we can set the current format (& push the stack) -# when we recognize the format name part of the format block. -def p_push_format_id(t): - 'push_format_id : ID' - try: - formatStack.push(formatMap[t[1]]) - t[0] = ('', '// format %s' % t[1]) - except KeyError: - error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1]) - -# Nested decode block: if the value of the current field matches the -# specified constant, do a nested decode on some other field. -def p_decode_stmt_decode(t): - 'decode_stmt : case_label COLON decode_block' - label = t[1] - codeObj = t[3] - # just wrap the decoding code from the block as a case in the - # outer switch statement. - codeObj.wrap_decode_block('\n%s:\n' % label) - codeObj.has_decode_default = (label == 'default') - t[0] = codeObj - -# Instruction definition (finally!). -def p_decode_stmt_inst(t): - 'decode_stmt : case_label COLON inst SEMI' - label = t[1] - codeObj = t[3] - codeObj.wrap_decode_block('\n%s:' % label, 'break;\n') - codeObj.has_decode_default = (label == 'default') - t[0] = codeObj - -# The case label is either a list of one or more constants or 'default' -def p_case_label_0(t): - 'case_label : intlit_list' - t[0] = ': '.join(map(lambda a: 'case %#x' % a, t[1])) - -def p_case_label_1(t): - 'case_label : DEFAULT' - t[0] = 'default' - -# -# The constant list for a decode case label must be non-empty, but may have -# one or more comma-separated integer literals in it. -# -def p_intlit_list_0(t): - 'intlit_list : INTLIT' - t[0] = [t[1]] - -def p_intlit_list_1(t): - 'intlit_list : intlit_list COMMA INTLIT' - t[0] = t[1] - t[0].append(t[3]) - -# Define an instruction using the current instruction format (specified -# by an enclosing format block). -# "<mnemonic>(<args>)" -def p_inst_0(t): - 'inst : ID LPAREN arg_list RPAREN' - # Pass the ID and arg list to the current format class to deal with. - currentFormat = formatStack.top() - codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno) - args = ','.join(map(str, t[3])) - args = re.sub('(?m)^', '//', args) - args = re.sub('^//', '', args) - comment = '\n// %s::%s(%s)\n' % (currentFormat.id, t[1], args) - codeObj.prepend_all(comment) - t[0] = codeObj - -# Define an instruction using an explicitly specified format: -# "<fmt>::<mnemonic>(<args>)" -def p_inst_1(t): - 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN' - try: - format = formatMap[t[1]] - except KeyError: - error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1]) - codeObj = format.defineInst(t[3], t[5], t.lexer.lineno) - comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5]) - codeObj.prepend_all(comment) - t[0] = codeObj - -# The arg list generates a tuple, where the first element is a list of -# the positional args and the second element is a dict containing the -# keyword args. -def p_arg_list_0(t): - 'arg_list : positional_arg_list COMMA keyword_arg_list' - t[0] = ( t[1], t[3] ) - -def p_arg_list_1(t): - 'arg_list : positional_arg_list' - t[0] = ( t[1], {} ) - -def p_arg_list_2(t): - 'arg_list : keyword_arg_list' - t[0] = ( [], t[1] ) - -def p_positional_arg_list_0(t): - 'positional_arg_list : empty' - t[0] = [] - -def p_positional_arg_list_1(t): - 'positional_arg_list : expr' - t[0] = [t[1]] - -def p_positional_arg_list_2(t): - 'positional_arg_list : positional_arg_list COMMA expr' - t[0] = t[1] + [t[3]] - -def p_keyword_arg_list_0(t): - 'keyword_arg_list : keyword_arg' - t[0] = t[1] - -def p_keyword_arg_list_1(t): - 'keyword_arg_list : keyword_arg_list COMMA keyword_arg' - t[0] = t[1] - t[0].update(t[3]) - -def p_keyword_arg(t): - 'keyword_arg : ID EQUALS expr' - t[0] = { t[1] : t[3] } - -# -# Basic expressions. These constitute the argument values of -# "function calls" (i.e. instruction definitions in the decode block) -# and default values for formal parameters of format functions. -# -# Right now, these are either strings, integers, or (recursively) -# lists of exprs (using Python square-bracket list syntax). Note that -# bare identifiers are trated as string constants here (since there -# isn't really a variable namespace to refer to). -# -def p_expr_0(t): - '''expr : ID - | INTLIT - | STRLIT - | CODELIT''' - t[0] = t[1] - -def p_expr_1(t): - '''expr : LBRACKET list_expr RBRACKET''' - t[0] = t[2] - -def p_list_expr_0(t): - 'list_expr : expr' - t[0] = [t[1]] - -def p_list_expr_1(t): - 'list_expr : list_expr COMMA expr' - t[0] = t[1] + [t[3]] - -def p_list_expr_2(t): - 'list_expr : empty' - t[0] = [] + # both the latter output blocks and the decode block are in + # the namespace + namespace_code = t[3] + t[4] + # pass it all back to the caller of yacc.parse() + t[0] = (isa_name, namespace, global_code, namespace_code) + + # ISA name declaration looks like "namespace <foo>;" + def p_name_decl(self, t): + 'name_decl : NAMESPACE ID SEMI' + t[0] = t[2] + + # 'opt_defs_and_outputs' is a possibly empty sequence of + # def and/or output statements. + def p_opt_defs_and_outputs_0(self, t): + 'opt_defs_and_outputs : empty' + t[0] = GenCode() + + def p_opt_defs_and_outputs_1(self, t): + 'opt_defs_and_outputs : defs_and_outputs' + t[0] = t[1] + + def p_defs_and_outputs_0(self, t): + 'defs_and_outputs : def_or_output' + t[0] = t[1] + + def p_defs_and_outputs_1(self, t): + 'defs_and_outputs : defs_and_outputs def_or_output' + t[0] = t[1] + t[2] + + # The list of possible definition/output statements. + def p_def_or_output(self, t): + '''def_or_output : def_format + | def_bitfield + | def_bitfield_struct + | def_template + | def_operand_types + | def_operands + | output_header + | output_decoder + | output_exec + | global_let''' + t[0] = t[1] + + # Output blocks 'output <foo> {{...}}' (C++ code blocks) are copied + # directly to the appropriate output section. + + # 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 + # format operation will reduce them back to single '%'s. + def process_output(self, s): + s = protect_non_subst_percents(s) + # protects cpu-specific symbols too + s = protect_cpu_symbols(s) + return substBitOps(s % self.templateMap) + + def p_output_header(self, t): + 'output_header : OUTPUT HEADER CODELIT SEMI' + t[0] = GenCode(header_output = self.process_output(t[3])) + + def p_output_decoder(self, t): + 'output_decoder : OUTPUT DECODER CODELIT SEMI' + t[0] = GenCode(decoder_output = self.process_output(t[3])) + + def p_output_exec(self, t): + 'output_exec : OUTPUT EXEC CODELIT SEMI' + t[0] = GenCode(exec_output = self.process_output(t[3])) + + # global let blocks 'let {{...}}' (Python code blocks) are + # executed directly when seen. Note that these execute in a + # special variable context 'exportContext' to prevent the code + # from polluting this script's namespace. + def p_global_let(self, t): + 'global_let : LET CODELIT SEMI' + updateExportContext() + exportContext["header_output"] = '' + exportContext["decoder_output"] = '' + exportContext["exec_output"] = '' + exportContext["decode_block"] = '' + try: + exec fixPythonIndentation(t[2]) in exportContext + except Exception, exc: + error(t.lexer.lineno, + 'error: %s in global let block "%s".' % (exc, t[2])) + t[0] = GenCode(header_output = exportContext["header_output"], + decoder_output = exportContext["decoder_output"], + exec_output = exportContext["exec_output"], + decode_block = exportContext["decode_block"]) + + # Define the mapping from operand type extensions to C++ types and + # bit widths (stored in operandTypeMap). + def p_def_operand_types(self, t): + 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI' + try: + userDict = eval('{' + t[3] + '}') + except Exception, exc: + error(t.lexer.lineno, + 'error: %s in def operand_types block "%s".' % (exc, t[3])) + buildOperandTypeMap(userDict, t.lexer.lineno) + t[0] = GenCode() # contributes nothing to the output C++ file + + # Define the mapping from operand names to operand classes and + # other traits. Stored in operandNameMap. + def p_def_operands(self, t): + 'def_operands : DEF OPERANDS CODELIT SEMI' + if not globals().has_key('operandTypeMap'): + error(t.lexer.lineno, + 'error: operand types must be defined before operands') + try: + userDict = eval('{' + t[3] + '}', exportContext) + except Exception, exc: + error(t.lexer.lineno, + 'error: %s in def operands block "%s".' % (exc, t[3])) + buildOperandNameMap(userDict, t.lexer.lineno) + t[0] = GenCode() # contributes nothing to the output C++ file + + # A bitfield definition looks like: + # 'def [signed] bitfield <ID> [<first>:<last>]' + # This generates a preprocessor macro in the output file. + def p_def_bitfield_0(self, t): + 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI' + expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8]) + if (t[2] == 'signed'): + expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr) + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + + # alternate form for single bit: 'def [signed] bitfield <ID> [<bit>]' + def p_def_bitfield_1(self, t): + 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI' + expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6]) + if (t[2] == 'signed'): + expr = 'sext<%d>(%s)' % (1, expr) + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + + # alternate form for structure member: 'def bitfield <ID> <ID>' + def p_def_bitfield_struct(self, t): + 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI' + if (t[2] != ''): + error(t.lexer.lineno, + 'error: structure bitfields are always unsigned.') + expr = 'machInst.%s' % t[5] + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + + def p_id_with_dot_0(self, t): + 'id_with_dot : ID' + t[0] = t[1] + + def p_id_with_dot_1(self, t): + 'id_with_dot : ID DOT id_with_dot' + t[0] = t[1] + t[2] + t[3] + + def p_opt_signed_0(self, t): + 'opt_signed : SIGNED' + t[0] = t[1] + + def p_opt_signed_1(self, t): + 'opt_signed : empty' + t[0] = '' + + def p_def_template(self, t): + 'def_template : DEF TEMPLATE ID CODELIT SEMI' + self.templateMap[t[3]] = Template(t[4]) + t[0] = GenCode() + + # An instruction format definition looks like + # "def format <fmt>(<params>) {{...}};" + def p_def_format(self, t): + 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI' + (id, params, code) = (t[3], t[5], t[7]) + defFormat(id, params, code, t.lexer.lineno) + t[0] = GenCode() + + # The formal parameter list for an instruction format is a + # possibly empty list of comma-separated parameters. Positional + # (standard, non-keyword) parameters must come first, followed by + # keyword parameters, followed by a '*foo' parameter that gets + # excess positional arguments (as in Python). Each of these three + # parameter categories is optional. + # + # Note that we do not support the '**foo' parameter for collecting + # otherwise undefined keyword args. Otherwise the parameter list + # is (I believe) identical to what is supported in Python. + # + # The param list generates a tuple, where the first element is a + # list of the positional params and the second element is a dict + # containing the keyword params. + def p_param_list_0(self, t): + 'param_list : positional_param_list COMMA nonpositional_param_list' + t[0] = t[1] + t[3] + + def p_param_list_1(self, t): + '''param_list : positional_param_list + | nonpositional_param_list''' + t[0] = t[1] + + def p_positional_param_list_0(self, t): + 'positional_param_list : empty' + t[0] = [] + + def p_positional_param_list_1(self, t): + 'positional_param_list : ID' + t[0] = [t[1]] + + def p_positional_param_list_2(self, t): + 'positional_param_list : positional_param_list COMMA ID' + t[0] = t[1] + [t[3]] + + def p_nonpositional_param_list_0(self, t): + 'nonpositional_param_list : keyword_param_list COMMA excess_args_param' + t[0] = t[1] + t[3] + + def p_nonpositional_param_list_1(self, t): + '''nonpositional_param_list : keyword_param_list + | excess_args_param''' + t[0] = t[1] + + def p_keyword_param_list_0(self, t): + 'keyword_param_list : keyword_param' + t[0] = [t[1]] + + def p_keyword_param_list_1(self, t): + 'keyword_param_list : keyword_param_list COMMA keyword_param' + t[0] = t[1] + [t[3]] + + def p_keyword_param(self, t): + 'keyword_param : ID EQUALS expr' + t[0] = t[1] + ' = ' + t[3].__repr__() + + def p_excess_args_param(self, t): + 'excess_args_param : ASTERISK ID' + # Just concatenate them: '*ID'. Wrap in list to be consistent + # with positional_param_list and keyword_param_list. + t[0] = [t[1] + t[2]] + + # End of format definition-related rules. + ############## + + # + # A decode block looks like: + # decode <field1> [, <field2>]* [default <inst>] { ... } + # + def p_decode_block(self, t): + 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE' + default_defaults = defaultStack.pop() + codeObj = t[5] + # use the "default defaults" only if there was no explicit + # default statement in decode_stmt_list + if not codeObj.has_decode_default: + codeObj += default_defaults + codeObj.wrap_decode_block('switch (%s) {\n' % t[2], '}\n') + t[0] = codeObj + + # The opt_default statement serves only to push the "default + # defaults" onto defaultStack. This value will be used by nested + # decode blocks, and used and popped off when the current + # decode_block is processed (in p_decode_block() above). + def p_opt_default_0(self, t): + 'opt_default : empty' + # no default specified: reuse the one currently at the top of + # the stack + defaultStack.push(defaultStack.top()) + # no meaningful value returned + t[0] = None + + def p_opt_default_1(self, t): + 'opt_default : DEFAULT inst' + # push the new default + codeObj = t[2] + codeObj.wrap_decode_block('\ndefault:\n', 'break;\n') + defaultStack.push(codeObj) + # no meaningful value returned + t[0] = None + + def p_decode_stmt_list_0(self, t): + 'decode_stmt_list : decode_stmt' + t[0] = t[1] + + def p_decode_stmt_list_1(self, t): + 'decode_stmt_list : decode_stmt decode_stmt_list' + if (t[1].has_decode_default and t[2].has_decode_default): + error(t.lexer.lineno, 'Two default cases in decode block') + t[0] = t[1] + t[2] + + # + # Decode statement rules + # + # There are four types of statements allowed in a decode block: + # 1. Format blocks 'format <foo> { ... }' + # 2. Nested decode blocks + # 3. Instruction definitions. + # 4. C preprocessor directives. + + + # Preprocessor directives found in a decode statement list are + # passed through to the output, replicated to all of the output + # code streams. This works well for ifdefs, so we can ifdef out + # both the declarations and the decode cases generated by an + # instruction definition. Handling them as part of the grammar + # makes it easy to keep them in the right place with respect to + # the code generated by the other statements. + def p_decode_stmt_cpp(self, t): + 'decode_stmt : CPPDIRECTIVE' + t[0] = GenCode(t[1], t[1], t[1], t[1]) + + # A format block 'format <foo> { ... }' sets the default + # instruction format used to handle instruction definitions inside + # the block. This format can be overridden by using an explicit + # format on the instruction definition or with a nested format + # block. + def p_decode_stmt_format(self, t): + 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE' + # The format will be pushed on the stack when 'push_format_id' + # is processed (see below). Once the parser has recognized + # the full production (though the right brace), we're done + # with the format, so now we can pop it. + formatStack.pop() + t[0] = t[4] + + # This rule exists so we can set the current format (& push the + # stack) when we recognize the format name part of the format + # block. + def p_push_format_id(self, t): + 'push_format_id : ID' + try: + formatStack.push(formatMap[t[1]]) + t[0] = ('', '// format %s' % t[1]) + except KeyError: + error(t.lexer.lineno, + 'instruction format "%s" not defined.' % t[1]) + + # Nested decode block: if the value of the current field matches + # the specified constant, do a nested decode on some other field. + def p_decode_stmt_decode(self, t): + 'decode_stmt : case_label COLON decode_block' + label = t[1] + codeObj = t[3] + # just wrap the decoding code from the block as a case in the + # outer switch statement. + codeObj.wrap_decode_block('\n%s:\n' % label) + codeObj.has_decode_default = (label == 'default') + t[0] = codeObj + + # Instruction definition (finally!). + def p_decode_stmt_inst(self, t): + 'decode_stmt : case_label COLON inst SEMI' + label = t[1] + codeObj = t[3] + codeObj.wrap_decode_block('\n%s:' % label, 'break;\n') + codeObj.has_decode_default = (label == 'default') + t[0] = codeObj + + # The case label is either a list of one or more constants or + # 'default' + def p_case_label_0(self, t): + 'case_label : intlit_list' + def make_case(intlit): + if intlit >= 2**32: + return 'case ULL(%#x)' % intlit + else: + return 'case %#x' % intlit + t[0] = ': '.join(map(make_case, t[1])) + + def p_case_label_1(self, t): + 'case_label : DEFAULT' + t[0] = 'default' + + # + # The constant list for a decode case label must be non-empty, but + # may have one or more comma-separated integer literals in it. + # + def p_intlit_list_0(self, t): + 'intlit_list : INTLIT' + t[0] = [t[1]] + + def p_intlit_list_1(self, t): + 'intlit_list : intlit_list COMMA INTLIT' + t[0] = t[1] + t[0].append(t[3]) + + # Define an instruction using the current instruction format + # (specified by an enclosing format block). + # "<mnemonic>(<args>)" + def p_inst_0(self, t): + 'inst : ID LPAREN arg_list RPAREN' + # Pass the ID and arg list to the current format class to deal with. + currentFormat = formatStack.top() + codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno) + args = ','.join(map(str, t[3])) + args = re.sub('(?m)^', '//', args) + args = re.sub('^//', '', args) + comment = '\n// %s::%s(%s)\n' % (currentFormat.id, t[1], args) + codeObj.prepend_all(comment) + t[0] = codeObj + + # Define an instruction using an explicitly specified format: + # "<fmt>::<mnemonic>(<args>)" + def p_inst_1(self, t): + 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN' + try: + format = formatMap[t[1]] + except KeyError: + error(t.lexer.lineno, + 'instruction format "%s" not defined.' % t[1]) + codeObj = format.defineInst(t[3], t[5], t.lexer.lineno) + comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5]) + codeObj.prepend_all(comment) + t[0] = codeObj + + # The arg list generates a tuple, where the first element is a + # list of the positional args and the second element is a dict + # containing the keyword args. + def p_arg_list_0(self, t): + 'arg_list : positional_arg_list COMMA keyword_arg_list' + t[0] = ( t[1], t[3] ) + + def p_arg_list_1(self, t): + 'arg_list : positional_arg_list' + t[0] = ( t[1], {} ) + + def p_arg_list_2(self, t): + 'arg_list : keyword_arg_list' + t[0] = ( [], t[1] ) + + def p_positional_arg_list_0(self, t): + 'positional_arg_list : empty' + t[0] = [] + + def p_positional_arg_list_1(self, t): + 'positional_arg_list : expr' + t[0] = [t[1]] + + def p_positional_arg_list_2(self, t): + 'positional_arg_list : positional_arg_list COMMA expr' + t[0] = t[1] + [t[3]] + + def p_keyword_arg_list_0(self, t): + 'keyword_arg_list : keyword_arg' + t[0] = t[1] + + def p_keyword_arg_list_1(self, t): + 'keyword_arg_list : keyword_arg_list COMMA keyword_arg' + t[0] = t[1] + t[0].update(t[3]) + + def p_keyword_arg(self, t): + 'keyword_arg : ID EQUALS expr' + t[0] = { t[1] : t[3] } + + # + # Basic expressions. These constitute the argument values of + # "function calls" (i.e. instruction definitions in the decode + # block) and default values for formal parameters of format + # functions. + # + # Right now, these are either strings, integers, or (recursively) + # lists of exprs (using Python square-bracket list syntax). Note + # that bare identifiers are trated as string constants here (since + # there isn't really a variable namespace to refer to). + # + def p_expr_0(self, t): + '''expr : ID + | INTLIT + | STRLIT + | CODELIT''' + t[0] = t[1] + + def p_expr_1(self, t): + '''expr : LBRACKET list_expr RBRACKET''' + t[0] = t[2] + + def p_list_expr_0(self, t): + 'list_expr : expr' + t[0] = [t[1]] + + def p_list_expr_1(self, t): + 'list_expr : list_expr COMMA expr' + t[0] = t[1] + [t[3]] + + def p_list_expr_2(self, t): + 'list_expr : empty' + t[0] = [] + + # + # Empty production... use in other rules for readability. + # + def p_empty(self, t): + 'empty :' + pass + + # Parse error handler. Note that the argument here is the + # offending *token*, not a grammar symbol (hence the need to use + # t.value) + def p_error(self, t): + if t: + error(t.lexer.lineno, "syntax error at '%s'" % t.value) + else: + error(0, "unknown syntax error", True) -# -# Empty production... use in other rules for readability. -# -def p_empty(t): - 'empty :' - pass - -# Parse error handler. Note that the argument here is the offending -# *token*, not a grammar symbol (hence the need to use t.value) -def p_error(t): - if t: - error(t.lexer.lineno, "syntax error at '%s'" % t.value) - else: - error(0, "unknown syntax error", True) + # END OF GRAMMAR RULES -# END OF GRAMMAR RULES -# # Now build the parser. -parser = yacc.yacc() - +parser = ISAParser() ##################################################################### # @@ -766,6 +768,11 @@ def expand_cpu_symbols_to_string(template): def protect_cpu_symbols(template): return re.sub(r'%(?=\(CPU_)', '%%', template) +# Protect any non-dict-substitution '%'s in a format string +# (i.e. those not followed by '(') +def protect_non_subst_percents(s): + return re.sub(r'%(?!\()', '%%', s) + ############### # GenCode class # @@ -839,7 +846,7 @@ exportContext = {} def updateExportContext(): exportContext.update(exportDict(*exportContextSymbols)) - exportContext.update(templateMap) + exportContext.update(parser.templateMap) def exportDict(*symNames): return dict([(s, eval(s)) for s in symNames]) @@ -1049,7 +1056,7 @@ class Template: # Build a dict ('myDict') to use for the template substitution. # Start with the template namespace. Make a copy since we're # going to modify it. - myDict = templateMap.copy() + myDict = parser.templateMap.copy() if isinstance(d, InstObjParams): # If we're dealing with an InstObjParams object, we need @@ -1463,6 +1470,16 @@ class MemOperand(Operand): def makeAccSize(self): return self.size +class PCOperand(Operand): + def makeConstructor(self): + return '' + + def makeRead(self): + return '%s = xc->readPC();\n' % self.base_name + + def makeWrite(self): + return 'xc->setPC(%s);\n' % self.base_name + class UPCOperand(Operand): def makeConstructor(self): return '' @@ -1975,8 +1992,7 @@ def parse_isa_desc(isa_desc_file, output_dir): fileNameStack.push((isa_desc_file, 0)) # Parse it. - (isa_name, namespace, global_code, namespace_code) = \ - parser.parse(isa_desc, lexer=lexer) + (isa_name, namespace, global_code, namespace_code) = parser.parse(isa_desc) # grab the last three path components of isa_desc_file to put in # the output diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py index 3433a8076..4e5400cef 100644 --- a/src/arch/micro_asm.py +++ b/src/arch/micro_asm.py @@ -34,10 +34,6 @@ import traceback # get type names from types import * -# Prepend the directory where the PLY lex & yacc modules are found -# to the search path. -sys.path[0:0] = [os.environ['M5_PLY']] - from ply import lex from ply import yacc diff --git a/src/arch/mips/BISystem.py b/src/arch/mips/BISystem.py index dd4e4fe25..a6e4091f2 100755 --- a/src/arch/mips/BISystem.py +++ b/src/arch/mips/BISystem.py @@ -28,10 +28,11 @@ # # Authors: Jaidev Patwardhan -from m5 import build_env +from m5.defines import buildEnv + from System import * -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: class BareIronMipsSystem(MipsSystem): type = 'BareIronMipsSystem' system_type = 34 diff --git a/src/arch/mips/MipsCPU.py b/src/arch/mips/MipsCPU.py index 81c6bdacf..48ee4171c 100644 --- a/src/arch/mips/MipsCPU.py +++ b/src/arch/mips/MipsCPU.py @@ -29,12 +29,13 @@ # Authors: Jaidev Patwardhan # Korey Sewell -from m5.SimObject import SimObject +from m5.defines import buildEnv from m5.params import * + from BaseCPU import BaseCPU class BaseMipsCPU(BaseCPU) - if build_env['TARGET_ISA'] == 'mips': + if buildEnv['TARGET_ISA'] == 'mips': CP0_IntCtl_IPTI = Param.Unsigned(0,"No Description") CP0_IntCtl_IPPCI = Param.Unsigned(0,"No Description") CP0_SrsCtl_HSS = Param.Unsigned(0,"No Description") diff --git a/src/arch/mips/MipsSystem.py b/src/arch/mips/MipsSystem.py index c3dcf4e0b..d271bd387 100644 --- a/src/arch/mips/MipsSystem.py +++ b/src/arch/mips/MipsSystem.py @@ -28,10 +28,10 @@ # # Authors: Jaidev Patwardhan -from m5.SimObject import SimObject +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env + from System import System class MipsSystem(System): @@ -42,7 +42,7 @@ class MipsSystem(System): system_type = Param.UInt64("Type of system we are emulating") system_rev = Param.UInt64("Revision of system we are emulating") -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: class LinuxMipsSystem(MipsSystem): type = 'LinuxMipsSystem' system_type = 34 diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc index 6e4f7afea..b8b02ae9e 100755 --- a/src/arch/mips/dsp.cc +++ b/src/arch/mips/dsp.cc @@ -463,6 +463,8 @@ MipsISA::dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl) uint64_t b_values[SIMD_MAX_VALS]; uint64_t c_values[SIMD_MAX_VALS]; + memset(c_values, 0, sizeof(c_values)); + simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED); simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED); @@ -743,7 +745,7 @@ MipsISA::dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac, int nvals = SIMD_NVALS[fmt]; uint64_t a_values[SIMD_MAX_VALS]; uint64_t b_values[SIMD_MAX_VALS]; - int64_t temp[2]; + int64_t temp[2] = {0, 0}; uint32_t ouflag = 0; simdUnpack(a, a_values, fmt, SIGNED); diff --git a/src/arch/mips/isa.hh b/src/arch/mips/isa.hh index 15c043dc0..165adff83 100644 --- a/src/arch/mips/isa.hh +++ b/src/arch/mips/isa.hh @@ -172,8 +172,11 @@ namespace MipsISA return reg; } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os) + {} + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion) + {} }; } diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa index adcb16137..161a52b06 100644 --- a/src/arch/mips/isa/formats/mem.isa +++ b/src/arch/mips/isa/formats/mem.isa @@ -619,7 +619,7 @@ def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; def format Prefetch(ea_code = {{ EA = Rs + disp; }}, mem_flags = [], pf_flags = [], inst_flags = []) {{ - pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_mem_flags = mem_flags + pf_flags + ['PREFETCH'] pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp'] diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index ee81fa18f..a2418cfb6 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -100,6 +100,7 @@ class MipsLinux : public Linux static const unsigned TIOCISATTY_ = 0x5480; static const unsigned TIOCGETS_ = 0x540d; static const unsigned TIOCGETA_ = 0x7417; + static const unsigned TCSETAW_ = 0x5403; // 2.6.15 kernel //@} /// For table(). @@ -126,6 +127,22 @@ class MipsLinux : public Linux /// assign themselves to process IDs reserved for /// the root users. static const int NUM_ROOT_PROCS = 2; + + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; #endif diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 53a24487f..c2a05b73b 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -51,7 +51,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename,"m5.eecs.umich.edu"); @@ -70,14 +71,16 @@ static SyscallReturn sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); - // unsigned nbytes = process->getSyscallArg(tc, 2); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + unsigned bufPtr = process->getSyscallArg(tc, index); + // unsigned nbytes = process->getSyscallArg(tc, index); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg<uint64_t> fpcr(bufPtr); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -97,15 +100,17 @@ static SyscallReturn sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); - // unsigned nbytes = process->getSyscallArg(tc, 2); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); + // unsigned nbytes = process->getSyscallArg(tc, index); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg<uint64_t> fpcr(bufPtr); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): " @@ -238,7 +243,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 113 */ SyscallDesc("vm86", unimplementedFunc), /* 114 */ SyscallDesc("wait4", unimplementedFunc), /* 115 */ SyscallDesc("swapoff", unimplementedFunc), - /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", sysinfoFunc<MipsLinux>), /* 117 */ SyscallDesc("ipc", unimplementedFunc), /* 118 */ SyscallDesc("fsync", unimplementedFunc), /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), @@ -413,12 +418,6 @@ MipsLinuxProcess::MipsLinuxProcess(LiveProcessParams * params, Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) { } -void -MipsLinuxProcess::startup() -{ - MipsLiveProcess::argsInit(MachineBytes, VMPageSize); -} - SyscallDesc* MipsLinuxProcess::getDesc(int callnum) { diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh index 5afde2be1..8c45014e0 100644 --- a/src/arch/mips/linux/process.hh +++ b/src/arch/mips/linux/process.hh @@ -43,8 +43,6 @@ class MipsLinuxProcess : public MipsLiveProcess /// Constructor. MipsLinuxProcess(LiveProcessParams * params, ObjectFile *objFile); - void startup(); - virtual SyscallDesc* getDesc(int callnum); /// The target system's hostname. diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index 3e9fb7c20..d96b0c81c 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -32,9 +32,15 @@ #include "arch/mips/isa_traits.hh" #include "arch/mips/process.hh" + #include "base/loader/object_file.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" + +#include "mem/page_table.hh" + +#include "sim/process.hh" +#include "sim/process_impl.hh" #include "sim/system.hh" using namespace std; @@ -62,14 +68,89 @@ MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params, void MipsLiveProcess::startup() { + Process::startup(); + argsInit(MachineBytes, VMPageSize); } +void +MipsLiveProcess::argsInit(int intSize, int pageSize) +{ + // load object file into target memory + objFile->loadSections(initVirtMem); + + // Calculate how much space we need for arg & env arrays. + int argv_array_size = intSize * (argv.size() + 1); + int envp_array_size = intSize * (envp.size() + 1); + int arg_data_size = 0; + for (vector<string>::size_type i = 0; i < argv.size(); ++i) { + arg_data_size += argv[i].size() + 1; + } + int env_data_size = 0; + for (vector<string>::size_type i = 0; i < envp.size(); ++i) { + env_data_size += envp[i].size() + 1; + } + + int space_needed = + argv_array_size + envp_array_size + arg_data_size + env_data_size; + if (space_needed < 32*1024) + space_needed = 32*1024; + + // set bottom of stack + stack_min = stack_base - space_needed; + // align it + stack_min = roundDown(stack_min, pageSize); + stack_size = stack_base - stack_min; + // map memory + pTable->allocate(stack_min, roundUp(stack_size, pageSize)); + + // map out initial stack contents + // ======== + // NOTE: Using uint32_t hardcodes MIPS32 and not MIPS64 + // even if MIPS64 was intended. This is because the + // copyStringArray function templates on the parameters. + // Elegant way to check intSize and vary between 32/64? + // ======== + uint32_t argv_array_base = stack_min + intSize; // room for argc + uint32_t envp_array_base = argv_array_base + argv_array_size; + uint32_t arg_data_base = envp_array_base + envp_array_size; + uint32_t env_data_base = arg_data_base + arg_data_size; + + // write contents to stack + uint32_t argc = argv.size(); + + if (intSize == 8) + argc = htog((uint64_t)argc); + else if (intSize == 4) + argc = htog((uint32_t)argc); + else + panic("Unknown int size"); + + + initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); + + copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); + + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); + + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + setSyscallArg(tc, 0, argc); + setSyscallArg(tc, 1, argv_array_base); + tc->setIntReg(StackPointerReg, stack_min); + + Addr prog_entry = objFile->entryPoint(); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); +} + + MipsISA::IntReg -MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i) +MipsLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return tc->readIntReg(FirstArgumentReg + i); + return tc->readIntReg(FirstArgumentReg + i++); } void diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index 87c62330f..f35ec8554 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -45,10 +45,12 @@ class MipsLiveProcess : public LiveProcess protected: MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile); - virtual void startup(); + void startup(); + + void argsInit(int intSize, int pageSize); public: - MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i); + MipsISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/power/PowerTLB.py b/src/arch/power/PowerTLB.py new file mode 100644 index 000000000..36dff5333 --- /dev/null +++ b/src/arch/power/PowerTLB.py @@ -0,0 +1,37 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 The University of Edinburgh +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Timothy M. Jones + +from m5.SimObject import SimObject +from m5.params import * + +class PowerTLB(SimObject): + type = 'PowerTLB' + cxx_class = 'PowerISA::TLB' + size = Param.Int(64, "TLB size") diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript new file mode 100644 index 000000000..1fb36eaab --- /dev/null +++ b/src/arch/power/SConscript @@ -0,0 +1,61 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 The University of Edinburgh +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Timothy M. Jones + +Import('*') + +if env['TARGET_ISA'] == 'power': +# Workaround for bug in SCons version > 0.97d20071212 +# Scons bug id: 2006 M5 Bug id: 308 + Dir('isa/formats') + Source('insts/branch.cc') + Source('insts/mem.cc') + Source('insts/integer.cc') + Source('insts/floating.cc') + Source('insts/condition.cc') + Source('insts/static_inst.cc') + Source('pagetable.cc') + Source('tlb.cc') + + SimObject('PowerTLB.py') + TraceFlag('Power') + + if not env['FULL_SYSTEM']: + Source('process.cc') + Source('linux/linux.cc') + Source('linux/process.cc') + + # Add in files generated by the ISA description. + isa_desc_files = env.ISADesc('isa/main.isa') + + # Only non-header files need to be compiled. + for f in isa_desc_files: + if not f.path.endswith('.hh'): + Source(f) + diff --git a/src/arch/power/SConsopts b/src/arch/power/SConsopts new file mode 100644 index 000000000..d762c2d58 --- /dev/null +++ b/src/arch/power/SConsopts @@ -0,0 +1,33 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 The University of Edinburgh +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Timothy M. Jones + +Import('*') + +all_isa_list.append('power') diff --git a/src/mem/slicc/symbols/Symbol.cc b/src/arch/power/faults.hh index 25af5ad47..eadcb7900 100644 --- a/src/mem/slicc/symbols/Symbol.cc +++ b/src/arch/power/faults.hh @@ -1,6 +1,6 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,48 +25,63 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ * + * Authors: Gabe Black + * Timothy M. Jones */ -#include "mem/slicc/symbols/Symbol.hh" +#ifndef __ARCH_POWER_FAULTS_HH__ +#define __ARCH_POWER_FAULTS_HH__ + +#include "sim/faults.hh" -Symbol::Symbol(string id, const Location& location, const Map<string, string>& pairs) +namespace PowerISA { - m_id = id; - m_location = location; - m_pairs = pairs; - if (!existPair("short")) { - addPair("short", m_id); - } - m_used = false; -} -Symbol::Symbol(string id, const Location& location) +class PowerFault : public FaultBase { - m_id = id; - m_location = location; - if (!existPair("short")) { - addPair("short", m_id); - } - m_used = false; -} + protected: + FaultName _name; + + PowerFault(FaultName name) + : _name(name) + { + } + + FaultName + name() const + { + return _name; + } +}; -const string& Symbol::lookupPair(const string& key) const + +class UnimplementedOpcodeFault : public PowerFault { - if (!existPair(key)) { - error("Value for pair '" + key + "' missing."); - } - return m_pairs.lookup(key); -} + public: + UnimplementedOpcodeFault() + : PowerFault("Unimplemented Opcode") + { + } +}; + + +class MachineCheckFault : public PowerFault +{ + public: + MachineCheckFault() + : PowerFault("Machine Check") + { + } +}; + -void Symbol::addPair(const string& key, const string& value) +static inline Fault +genMachineCheckFault() { - if (existPair(key)) { - warning("Pair key '" + key + "' re-defined. new: '" + value + "' old: '" + lookupPair(key) + "'"); - } - m_pairs.add(key, value); + return new MachineCheckFault(); } + +} // PowerISA namespace + +#endif // __ARCH_POWER_FAULTS_HH__ diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc new file mode 100644 index 000000000..3f4346c97 --- /dev/null +++ b/src/arch/power/insts/branch.cc @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/branch.hh" +#include "base/loader/symtab.hh" + +using namespace PowerISA; + +const std::string & +PCDependentDisassembly::disassemble(Addr pc, const SymbolTable *symtab) const +{ + if (!cachedDisassembly || + pc != cachedPC || symtab != cachedSymtab) + { + if (cachedDisassembly) + delete cachedDisassembly; + + cachedDisassembly = + new std::string(generateDisassembly(pc, symtab)); + cachedPC = pc; + cachedSymtab = symtab; + } + + return *cachedDisassembly; +} + +Addr +BranchPCRel::branchTarget(Addr pc) const +{ + return (uint32_t)(pc + disp); +} + +std::string +BranchPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + Addr target = pc + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); +} + +Addr +BranchNonPCRel::branchTarget(Addr pc) const +{ + return targetAddr; +} + +std::string +BranchNonPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + std::string str; + if (symtab && symtab->findSymbol(targetAddr, str)) + ss << str; + else + ccprintf(ss, "0x%x", targetAddr); + + return ss.str(); +} + +Addr +BranchPCRelCond::branchTarget(Addr pc) const +{ + return (uint32_t)(pc + disp); +} + +std::string +BranchPCRelCond::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ss << bo << ", " << bi << ", "; + + Addr target = pc + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); +} + +Addr +BranchNonPCRelCond::branchTarget(Addr pc) const +{ + return targetAddr; +} + +std::string +BranchNonPCRelCond::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ss << bo << ", " << bi << ", "; + + std::string str; + if (symtab && symtab->findSymbol(targetAddr, str)) + ss << str; + else + ccprintf(ss, "0x%x", targetAddr); + + return ss.str(); +} + +Addr +BranchRegCond::branchTarget(ThreadContext *tc) const +{ + uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1]); + return (regVal & 0xfffffffc); +} + +std::string +BranchRegCond::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ss << bo << ", " << bi << ", "; + + return ss.str(); +} diff --git a/src/arch/power/insts/branch.hh b/src/arch/power/insts/branch.hh new file mode 100644 index 000000000..dd00e42c3 --- /dev/null +++ b/src/arch/power/insts/branch.hh @@ -0,0 +1,241 @@ +/* Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_BRANCH_HH__ +#define __ARCH_POWER_INSTS_BRANCH_HH__ + +#include "arch/power/insts/static_inst.hh" + +namespace PowerISA +{ + +/** + * Base class for instructions whose disassembly is not purely a + * function of the machine instruction (i.e., it depends on the + * PC). This class overrides the disassemble() method to check + * the PC and symbol table values before re-using a cached + * disassembly string. This is necessary for branches and jumps, + * where the disassembly string includes the target address (which + * may depend on the PC and/or symbol table). + */ +class PCDependentDisassembly : public PowerStaticInst +{ + protected: + /// Cached program counter from last disassembly + mutable Addr cachedPC; + /// Cached symbol table pointer from last disassembly + mutable const SymbolTable *cachedSymtab; + + /// Constructor + PCDependentDisassembly(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + cachedPC(0), cachedSymtab(0) + { + } + + const std::string & + disassemble(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for unconditional, PC-relative branches. + */ +class BranchPCRel : public PCDependentDisassembly +{ + protected: + + /// Displacement + uint32_t disp; + + /// Constructor. + BranchPCRel(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(machInst.li << 2) + { + // If bit 26 is 1 then sign extend + if (disp & 0x2000000) { + disp |= 0xfc000000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for unconditional, non PC-relative branches. + */ +class BranchNonPCRel : public PCDependentDisassembly +{ + protected: + + /// Target address + uint32_t targetAddr; + + /// Constructor. + BranchNonPCRel(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + targetAddr(machInst.li << 2) + { + // If bit 26 is 1 then sign extend + if (targetAddr & 0x2000000) { + targetAddr |= 0xfc000000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for conditional branches. + */ +class BranchCond : public PCDependentDisassembly +{ + protected: + + /// Fields needed for conditions + uint32_t bo; + uint32_t bi; + + /// Constructor. + BranchCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + bo(machInst.bo), + bi(machInst.bi) + { + } + + inline bool + ctrOk(uint32_t& ctr) const + { + bool ctr_ok; + if (bo & 4) { + ctr_ok = true; + } else { + ctr--; + if (ctr != 0) { + ctr_ok = ((bo & 2) == 0); + } else { + ctr_ok = ((bo & 2) != 0); + } + } + return ctr_ok; + } + + inline bool + condOk(uint32_t cr) const + { + bool cond_ok; + if (bo & 16) { + cond_ok = true; + } else { + cond_ok = (((cr >> (31 - bi)) & 1) == ((bo >> 3) & 1)); + } + return cond_ok; + } +}; + +/** + * Base class for conditional, PC-relative branches. + */ +class BranchPCRelCond : public BranchCond +{ + protected: + + /// Displacement + uint32_t disp; + + /// Constructor. + BranchPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : BranchCond(mnem, _machInst, __opClass), + disp(machInst.bd << 2) + { + // If bit 16 is 1 then sign extend + if (disp & 0x8000) { + disp |= 0xffff0000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for conditional, non PC-relative branches. + */ +class BranchNonPCRelCond : public BranchCond +{ + protected: + + /// Target address + uint32_t targetAddr; + + /// Constructor. + BranchNonPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : BranchCond(mnem, _machInst, __opClass), + targetAddr(machInst.bd << 2) + { + // If bit 16 is 1 then sign extend + if (targetAddr & 0x8000) { + targetAddr |= 0xffff0000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for conditional, register-based branches + */ +class BranchRegCond : public BranchCond +{ + protected: + + /// Constructor. + BranchRegCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : BranchCond(mnem, _machInst, __opClass) + { + } + + Addr branchTarget(ThreadContext *tc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_BRANCH_HH__ diff --git a/src/mem/slicc/symbols/Var.cc b/src/arch/power/insts/condition.cc index a6e8dfd55..0a942a982 100644 --- a/src/mem/slicc/symbols/Var.cc +++ b/src/arch/power/insts/condition.cc @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,33 +24,36 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones */ -/* - * $Id$ - * - * */ +#include "arch/power/insts/condition.hh" -#include "mem/slicc/symbols/Var.hh" -#include "mem/slicc/symbols/StateMachine.hh" +using namespace PowerISA; -Var::Var(string id, const Location& location, - Type* type_ptr, string code, - const Map<string, string>& pairs, - StateMachine* machine_ptr) : Symbol(id, location, pairs) +std::string +CondLogicOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - if (machine_ptr == NULL) { - m_c_id = id; - } else { - m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name - } - - m_machine_ptr = machine_ptr; - m_type_ptr = type_ptr; - m_code = code; + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Format is <mnemonic> bt, ba, bb + ss << bt << ", " << ba << ", " << bb; + + return ss.str(); } -void Var::print(ostream& out) const +std::string +CondMoveOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - out << "[Var id: " << m_c_id << "]" << endl; + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Format is <mnemonic> bf, bfa + ss << bf << ", " << bfa; + + return ss.str(); } diff --git a/src/mem/slicc/ast/DeclAST.hh b/src/arch/power/insts/condition.hh index d9e4555b4..a23667d9e 100644 --- a/src/mem/slicc/ast/DeclAST.hh +++ b/src/arch/power/insts/condition.hh @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,61 +24,63 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * DeclAST.hh - * - * Description: - * - * $Id$ * + * Authors: Timothy M. Jones */ -#ifndef DECLAST_H -#define DECLAST_H +#ifndef __ARCH_POWER_INSTS_CONDITION_HH__ +#define __ARCH_POWER_INSTS_CONDITION_HH__ -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" -#include "mem/slicc/ast/PairListAST.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/TypeAST.hh" +#include "arch/power/insts/static_inst.hh" +#include "base/cprintf.hh" -class DeclAST : public AST { -public: - // Constructors - DeclAST(PairListAST* pairs_ptr) : AST(pairs_ptr->getPairs()) {} - - // Destructor - virtual ~DeclAST() {} +namespace PowerISA +{ - // Public Methods - virtual void generate() = 0; - virtual void findMachines() {}; +/** + * Class for condition register logical operations. + */ +class CondLogicOp : public PowerStaticInst +{ + protected: - // void print(ostream& out) const; -private: - // Private Methods + uint32_t ba; + uint32_t bb; + uint32_t bt; - // Private copy constructor and assignment operator - // DeclAST(const DeclAST& obj); - // DeclAST& operator=(const DeclAST& obj); + /// Constructor + CondLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + ba(machInst.ba), + bb(machInst.bb), + bt(machInst.bt) + { + } - // Data Members (m_ prefix) + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; -// Output operator declaration -ostream& operator<<(ostream& out, const DeclAST& obj); +/** + * Class for condition register move operations. + */ +class CondMoveOp : public PowerStaticInst +{ + protected: + + uint32_t bf; + uint32_t bfa; -// ******************* Definitions ******************* + /// Constructor + CondMoveOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + bf(machInst.bf), + bfa(machInst.bfa) + { + } -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const DeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace -#endif //DECLAST_H +#endif //__ARCH_POWER_INSTS_CONDITION_HH__ diff --git a/src/arch/power/insts/floating.cc b/src/arch/power/insts/floating.cc new file mode 100644 index 000000000..f5c34ee2a --- /dev/null +++ b/src/arch/power/insts/floating.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/floating.hh" + +using namespace PowerISA; + +std::string +FloatOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the (possibly) two source registers + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); +} diff --git a/src/arch/power/insts/floating.hh b/src/arch/power/insts/floating.hh new file mode 100644 index 000000000..2b2668409 --- /dev/null +++ b/src/arch/power/insts/floating.hh @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + * Korey Sewell + */ + +#ifndef __ARCH_POWER_INSTS_FLOATING_HH__ +#define __ARCH_POWER_INSTS_FLOATING_HH__ + +#include "arch/power/insts/static_inst.hh" +#include "base/cprintf.hh" +#include "base/bitfield.hh" + +namespace PowerISA +{ + +/** + * Base class for floating point operations. + */ +class FloatOp : public PowerStaticInst +{ + protected: + + bool rcSet; + + /// Constructor + FloatOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass) + { + } + + // Test for NaN (maximum biased exponent & non-zero fraction) + inline bool + isNan(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 23) == 0xFF) && bits(val_bits, 22, 0)); + } + + inline bool + isNan(uint64_t val_bits) const + { + return ((bits(val_bits, 62, 52) == 0x7FF) && bits(val_bits, 51, 0)); + } + + inline bool + isNan(float val) const + { + void *val_ptr = &val; + uint32_t val_bits = *(uint32_t *) val_ptr; + return isNan(val_bits); + } + + inline bool + isNan(double val) const + { + void *val_ptr = &val; + uint64_t val_bits = *(uint64_t *) val_ptr; + return isNan(val_bits); + } + + // Test for SNaN (NaN with high order bit of fraction set to 0) + inline bool + isSnan(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 22) == 0x1FE) && bits(val_bits, 22, 0)); + } + + // Test for QNaN (NaN with high order bit of fraction set to 1) + inline bool + isQnan(uint32_t val_bits) const + { + return (bits(val_bits, 30, 22) == 0x1FF); + } + + // Test for infinity (maximum biased exponent and zero fraction) + inline bool + isInfinity(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 23) == 0xFF) && !bits(val_bits, 22, 0)); + } + + // Test for normalized numbers (biased exponent in the range 1 to 254) + inline bool + isNormalized(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 23) != 0xFF) && bits(val_bits, 22, 0)); + } + + // Test for denormalized numbers (biased exponent of zero and + // non-zero fraction) + inline bool + isDenormalized(uint32_t val_bits) const + { + return (!bits(val_bits, 30, 23) && bits(val_bits, 22, 0)); + } + + // Test for zero (biased exponent of zero and fraction of zero) + inline bool + isZero(uint32_t val_bits) const + { + return (!bits(val_bits, 30, 23) && !bits(val_bits, 22, 0)); + } + + // Test for negative + inline bool + isNegative(uint32_t val_bits) const + { + return (bits(val_bits, 31)); + } + + // Compute the CR field + inline uint32_t + makeCRField(double a, double b) const + { + uint32_t c = 0; + if (isNan(a) || isNan(b)) { c = 0x1; } + else if (a < b) { c = 0x8; } + else if (a > b) { c = 0x4; } + else { c = 0x2; } + return c; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_FLOATING_HH__ diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc new file mode 100644 index 000000000..1f81a15dc --- /dev/null +++ b/src/arch/power/insts/integer.cc @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/integer.hh" + +using namespace std; +using namespace PowerISA; + +string +IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + bool printDest = true; + bool printSrcs = true; + bool printSecondSrc = true; + + // Generate the correct mnemonic + string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("or") && _srcRegIdx[0] == _srcRegIdx[1]) { + myMnemonic = "mr"; + printSecondSrc = false; + } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) { + printDest = false; + } else if (!myMnemonic.compare("mflr")) { + printSrcs = false; + } + + // Additional characters depending on isa bits being set + if (oeSet) myMnemonic = myMnemonic + "o"; + if (rcSet) myMnemonic = myMnemonic + "."; + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (_numDestRegs > 0 && printDest) { + printReg(ss, _destRegIdx[0]); + } + + // Print the (possibly) two source registers + if (_numSrcRegs > 0 && printSrcs) { + if (_numDestRegs > 0 && printDest) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + if (_numSrcRegs > 1 && printSecondSrc) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); +} + + +string +IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + + // Generate the correct mnemonic + string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("addi") && _numSrcRegs == 0) { + myMnemonic = "li"; + } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) { + myMnemonic = "lis"; + } + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + } + + // Print the immediate value last + ss << ", " << (int32_t)imm; + + return ss.str(); +} + + +string +IntShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + } + + // Print the shift + ss << ", " << sh; + + return ss.str(); +} + + +string +IntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + } + + // Print the shift, mask begin and mask end + ss << ", " << sh << ", " << mb << ", " << me; + + return ss.str(); +} diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh new file mode 100644 index 000000000..b4b96d5dc --- /dev/null +++ b/src/arch/power/insts/integer.hh @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_INTEGER_HH__ +#define __ARCH_POWER_INSTS_INTEGER_HH__ + +#include "arch/power/insts/static_inst.hh" +#include "base/cprintf.hh" +#include "base/bitfield.hh" + +namespace PowerISA +{ + +/** + * We provide a base class for integer operations and then inherit for + * several other classes. These specialise for instructions using immediate + * values and also rotate instructions. We also need to have versions that + * consider the Rc and OE bits. + */ + +/** + * Base class for integer operations. + */ +class IntOp : public PowerStaticInst +{ + protected: + + bool rcSet; + bool oeSet; + + // Needed for srawi only + uint32_t sh; + + /// Constructor + IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + rcSet(false), oeSet(false) + { + } + + /* Compute the CR (condition register) field using signed comparison */ + inline uint32_t + makeCRField(int32_t a, int32_t b, uint32_t xerSO) const + { + uint32_t c = xerSO; + + /* We've pre-shifted the immediate values here */ + if (a < b) { c += 0x8; } + else if (a > b) { c += 0x4; } + else { c += 0x2; } + return c; + } + + /* Compute the CR (condition register) field using unsigned comparison */ + inline uint32_t + makeCRField(uint32_t a, uint32_t b, uint32_t xerSO) const + { + uint32_t c = xerSO; + + /* We've pre-shifted the immediate values here */ + if (a < b) { c += 0x8; } + else if (a > b) { c += 0x4; } + else { c += 0x2; } + return c; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for integer immediate (signed and unsigned) operations. + */ +class IntImmOp : public IntOp +{ + protected: + + int32_t imm; + uint32_t uimm; + + /// Constructor + IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntOp(mnem, _machInst, __opClass), + imm(sext<16>(machInst.si)), + uimm(machInst.si) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for integer operations with a shift. + */ +class IntShiftOp : public IntOp +{ + protected: + + uint32_t sh; + + /// Constructor + IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntOp(mnem, _machInst, __opClass), + sh(machInst.sh) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for integer rotate operations. + */ +class IntRotateOp : public IntShiftOp +{ + protected: + + uint32_t mb; + uint32_t me; + uint32_t fullMask; + + /// Constructor + IntRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntShiftOp(mnem, _machInst, __opClass), + mb(machInst.mb), + me(machInst.me) + { + if (me >= mb) { + fullMask = mask(31 - mb, 31 - me); + } else { + fullMask = ~mask(31 - (me + 1), 31 - (mb - 1)); + } + } + + uint32_t + rotateValue(uint32_t rs, uint32_t shift) const + { + uint32_t n = shift & 31; + return (rs << n) | (rs >> (32 - n)); + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_INTEGER_HH__ diff --git a/src/mem/slicc/ast/DeclListAST.cc b/src/arch/power/insts/mem.cc index 8337d714b..447efa2f4 100644 --- a/src/mem/slicc/ast/DeclListAST.cc +++ b/src/arch/power/insts/mem.cc @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,62 +24,51 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * DeclListAST.C - * - * Description: See DeclListAST.hh - * - * $Id$ * + * Authors: Timothy M. Jones */ -#include "mem/slicc/ast/DeclListAST.hh" +#include "arch/power/insts/mem.hh" +#include "base/loader/symtab.hh" -DeclListAST::DeclListAST(Vector<DeclAST*>* vec_ptr) - : AST() -{ - assert(vec_ptr != NULL); - m_vec_ptr = vec_ptr; -} +using namespace PowerISA; -// Singleton constructor. -DeclListAST::DeclListAST(DeclAST* Decl_ptr) - : AST() +std::string +MemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - assert(Decl_ptr != NULL); - m_vec_ptr = new Vector<DeclAST*>; - m_vec_ptr->insertAtTop(Decl_ptr); + return csprintf("%-10s", mnemonic); } -DeclListAST::~DeclListAST() +std::string +MemDispOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - int size = m_vec_ptr->size(); - for(int i=0; i<size; i++) { - delete (*m_vec_ptr)[i]; - } - delete m_vec_ptr; -} + std::stringstream ss; -void DeclListAST::generate() const -{ - int size = m_vec_ptr->size(); - for(int i=0; i<size; i++) { - (*m_vec_ptr)[i]->generate(); - } -} + ccprintf(ss, "%-10s ", mnemonic); -void DeclListAST::findMachines() const -{ - int size = m_vec_ptr->size(); - for(int i=0; i<size; i++) { - (*m_vec_ptr)[i]->findMachines(); - } -} + // Print the destination only for a load + if (!flags[IsStore]) { + if (_numDestRegs > 0) { -void DeclListAST::print(ostream& out) const -{ - assert(m_vec_ptr != NULL); - out << "[DeclListAST: " << *m_vec_ptr << "]"; + // If the instruction updates the source register with the + // EA, then this source register is placed in position 0, + // therefore we print the last destination register. + printReg(ss, _destRegIdx[_numDestRegs-1]); + } + } + + // Print the data register for a store + else { + printReg(ss, _srcRegIdx[1]); + } + + // Print the displacement + ss << ", " << (int32_t)disp; + + // Print the address register + ss << "("; + printReg(ss, _srcRegIdx[0]); + ss << ")"; + + return ss.str(); } diff --git a/src/mem/slicc/ast/TypeDeclAST.cc b/src/arch/power/insts/mem.hh index bbf2f8491..329dafe57 100644 --- a/src/mem/slicc/ast/TypeDeclAST.cc +++ b/src/arch/power/insts/mem.hh @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,62 +24,68 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeDeclAST.C - * - * Description: See TypeDeclAST.hh - * - * $Id: TypeDeclAST.C,v 3.1 2003/03/22 15:15:17 xu Exp $ * + * Authors: Timothy M. Jones */ -#include "mem/slicc/ast/TypeDeclAST.hh" -#include "mem/slicc/main.hh" -#include "mem/slicc/symbols/SymbolTable.hh" +#ifndef __ARCH_POWER_MEM_HH__ +#define __ARCH_POWER_MEM_HH__ -TypeDeclAST::TypeDeclAST(TypeAST* type_ast_ptr, - PairListAST* pairs_ptr, - Vector<TypeFieldAST*>* field_vec_ptr) - : DeclAST(pairs_ptr) +#include "arch/power/insts/static_inst.hh" + +namespace PowerISA { - m_type_ast_ptr = type_ast_ptr; - m_field_vec_ptr = field_vec_ptr; -} -TypeDeclAST::~TypeDeclAST() +/** + * Base class for memory operations. + */ +class MemOp : public PowerStaticInst { - delete m_type_ast_ptr; - if (m_field_vec_ptr != NULL) { - int size = m_field_vec_ptr->size(); - for(int i=0; i<size; i++) { - delete (*m_field_vec_ptr)[i]; + protected: + + /// Memory request flags. See mem_req_base.hh. + unsigned memAccessFlags; + /// Pointer to EAComp object. + const StaticInstPtr eaCompPtr; + /// Pointer to MemAcc object. + const StaticInstPtr memAccPtr; + + /// Constructor + MemOp(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : PowerStaticInst(mnem, _machInst, __opClass), + memAccessFlags(0), + eaCompPtr(_eaCompPtr), + memAccPtr(_memAccPtr) + { } - delete m_field_vec_ptr; - } -} -void TypeDeclAST::generate() + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for memory operations with displacement. + */ +class MemDispOp : public MemOp { - string machine_name; - string id = m_type_ast_ptr->toString(); + protected: - // Make the new type - Type* new_type_ptr = new Type(id, getLocation(), getPairs(), - g_sym_table.getStateMachine()); - g_sym_table.newSym(new_type_ptr); + int16_t disp; - // Add all of the fields of the type to it - if (m_field_vec_ptr != NULL) { - int size = m_field_vec_ptr->size(); - for(int i=0; i<size; i++) { - (*m_field_vec_ptr)[i]->generate(new_type_ptr); + /// Constructor + MemDispOp(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : MemOp(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), + disp(machInst.d) + { } - } -} -void TypeDeclAST::print(ostream& out) const -{ - out << "[TypeDecl: " << m_type_ast_ptr->toString() << "]"; -} + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_MEM_HH__ diff --git a/src/arch/power/insts/misc.cc b/src/arch/power/insts/misc.cc new file mode 100644 index 000000000..913030b61 --- /dev/null +++ b/src/arch/power/insts/misc.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/misc.hh" + +using namespace PowerISA; + +std::string +MiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the (possibly) two source registers + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); +} diff --git a/src/mem/slicc/ast/LiteralExprAST.cc b/src/arch/power/insts/misc.hh index 4e384a3b3..dd4941b93 100644 --- a/src/mem/slicc/ast/LiteralExprAST.cc +++ b/src/arch/power/insts/misc.hh @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,31 +24,34 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * LiteralExprAST.C - * - * Description: See LiteralExprAST.hh - * - * $Id: LiteralExprAST.C,v 3.1 2002/10/22 21:27:52 milo Exp $ * + * Authors: Timothy M. Jones */ -#include "mem/slicc/ast/LiteralExprAST.hh" +#ifndef __ARCH_POWER_INSTS_MISC_HH__ +#define __ARCH_POWER_INSTS_MISC_HH__ + +#include "arch/power/insts/static_inst.hh" -Type* LiteralExprAST::generate(string& code) const +namespace PowerISA { - if (m_type == "string") { - code += "(\"" + *m_lit_ptr + "\")"; - } else { - code += "(" + *m_lit_ptr + ")"; - } - - Type* type_ptr = g_sym_table.getType(m_type); - if (type_ptr == NULL) { - // Can't find the type - error("Internal: can't primitive type '" + m_type + "'"); - } - return type_ptr; -} + +/** + * Class for misc operations. + */ +class MiscOp : public PowerStaticInst +{ + protected: + + /// Constructor + MiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_MISC_HH__ diff --git a/src/arch/power/insts/static_inst.cc b/src/arch/power/insts/static_inst.cc new file mode 100644 index 000000000..1982744bf --- /dev/null +++ b/src/arch/power/insts/static_inst.cc @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/static_inst.hh" + +using namespace PowerISA; + +void +PowerStaticInst::printReg(std::ostream &os, int reg) const +{ + if (reg < FP_Base_DepTag) { + ccprintf(os, "r%d", reg); + } else if (reg < Ctrl_Base_DepTag) { + ccprintf(os, "f%d", reg - FP_Base_DepTag); + } else { + switch (reg - Ctrl_Base_DepTag) { + case 0: ccprintf(os, "cr"); break; + case 1: ccprintf(os, "xer"); break; + case 2: ccprintf(os, "lr"); break; + case 3: ccprintf(os, "ctr"); break; + default: ccprintf(os, "unknown_reg"); + } + } +} + +std::string +PowerStaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + return ss.str(); +} diff --git a/src/mem/slicc/ast/PairListAST.hh b/src/arch/power/insts/static_inst.hh index 7edcdc1e7..399e75371 100644 --- a/src/mem/slicc/ast/PairListAST.hh +++ b/src/arch/power/insts/static_inst.hh @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,58 +24,47 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PairListAST.hh - * - * Description: - * - * $Id$ * + * Authors: Timothy M. Jones */ -#ifndef PairListAST_H -#define PairListAST_H +#ifndef __ARCH_POWER_INSTS_STATICINST_HH__ +#define __ARCH_POWER_INSTS_STATICINST_HH__ -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" -#include "mem/slicc/ast/PairAST.hh" +#include "base/trace.hh" +#include "cpu/static_inst.hh" +namespace PowerISA +{ -class PairListAST : public AST { -public: - // Constructors - PairListAST() : AST() {} +class PowerStaticInst : public StaticInst +{ + protected: - // Destructor - //~PairListAST(); + // Constructor + PowerStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } - // Public Methods - void addPair(PairAST* pair_ptr); - void print(ostream& out) const; -private: - // Private Methods + // Insert a condition value into a CR (condition register) field + inline uint32_t + insertCRField(uint32_t cr, uint32_t bf, uint32_t value) const + { + uint32_t bits = value << ((7 - bf) * 4); + uint32_t mask = ~(0xf << ((7 - bf) * 4)); + return (cr & mask) | bits; + } - // Private copy constructor and assignment operator - PairListAST(const PairListAST& obj); - PairListAST& operator=(const PairListAST& obj); + /// Print a register name for disassembly given the unique + /// dependence tag number (FP or int). + void + printReg(std::ostream &os, int reg) const; - // Data Members (m_ prefix) + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; -// Output operator declaration -ostream& operator<<(ostream& out, const PairListAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const PairListAST& obj) -{ - obj.print(out); - out << flush; - return out; -} +} // PowerISA namespace -#endif //PairListAST_H +#endif //__ARCH_POWER_INSTS_STATICINST_HH__ diff --git a/src/arch/power/isa.hh b/src/arch/power/isa.hh new file mode 100644 index 000000000..ba1b5018d --- /dev/null +++ b/src/arch/power/isa.hh @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2009 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_ISA_HH__ +#define __ARCH_POWER_ISA_HH__ + +#include "arch/power/registers.hh" +#include "arch/power/types.hh" +#include "base/misc.hh" + +class ThreadContext; +class Checkpoint; +class EventManager; + +namespace PowerISA +{ + +class ISA +{ + protected: + MiscReg dummy; + MiscReg miscRegs[NumMiscRegs]; + + public: + void + clear() + { + } + + MiscReg + readMiscRegNoEffect(int misc_reg) + { + fatal("Power does not currently have any misc regs defined\n"); + return dummy; + } + + MiscReg + readMiscReg(int misc_reg, ThreadContext *tc) + { + fatal("Power does not currently have any misc regs defined\n"); + return dummy; + } + + void + setMiscRegNoEffect(int misc_reg, const MiscReg &val) + { + fatal("Power does not currently have any misc regs defined\n"); + } + + void + setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) + { + fatal("Power does not currently have any misc regs defined\n"); + } + + int + flattenIntIndex(int reg) + { + return reg; + } + + int + flattenFloatIndex(int reg) + { + return reg; + } + + void + serialize(EventManager *em, std::ostream &os) + { + } + + void + unserialize(EventManager *em, Checkpoint *cp, const std::string §ion) + { + } + + ISA() + { + clear(); + } +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_ISA_HH__ diff --git a/src/arch/power/isa/bitfields.isa b/src/arch/power/isa/bitfields.isa new file mode 100644 index 000000000..8cd323ad5 --- /dev/null +++ b/src/arch/power/isa/bitfields.isa @@ -0,0 +1,84 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Bitfield definitions. +// +// The endianness is the opposite to what's used here, so things +// are reversed sometimes. Not sure of a fix to this though... + +// Opcode fields +def bitfield OPCODE <31:26>; +def bitfield X_XO <10:0>; +def bitfield XO_XO <10:1>; +def bitfield A_XO <5:1>; + +// Register fields +def bitfield RA <20:16>; +def bitfield RB <15:11>; +def bitfield RS <25:21>; +def bitfield RT <25:21>; +def bitfield FRA <20:16>; +def bitfield FRB <15:11>; +def bitfield FRC <10:6>; +def bitfield FRS <25:21>; +def bitfield FRT <25:21>; + +// The record bit can be in two positions +// Used to enable setting of the condition register +def bitfield RC31 <0>; +def bitfield RC21 <10>; + +// Used to enable setting of the overflow flags +def bitfield OE <10>; + +// SPR field for mtspr instruction +def bitfield SPR <20:11>; + +// FXM field for mtcrf instruction +def bitfield FXM <19:12>; + +// Branch fields +def bitfield LK <0>; +def bitfield AA <1>; + +// Specifies a CR or FPSCR field +def bitfield BF <25:23>; + +// Fields for FPSCR manipulation instructions +def bitfield FLM <24:17>; +def bitfield L <25>; +def bitfield W <16>; +// Named so to avoid conflicts with range.hh +def bitfield U_FIELD <15:12>; + +// Field for specifying a bit in CR or FPSCR +def bitfield BT <25:21>; diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa new file mode 100644 index 000000000..3252ff14a --- /dev/null +++ b/src/arch/power/isa/decoder.isa @@ -0,0 +1,593 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// The actual Power ISA decoder +// ------------------------------ +// +// I've used the Power ISA Book I v2.06 for instruction formats, +// opcode numbers, register names, etc. +// +decode OPCODE default Unknown::unknown() { + + format IntImmOp { + 10: cmpli({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra, (uint32_t)uimm, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + 11: cmpi({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra.sw, (int32_t)imm, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + } + + // Some instructions use bits 21 - 30, others 22 - 30. We have to use + // the larger size to account for all opcodes. For those that use the + // smaller value, the OE bit is bit 21. Therefore, we have two versions + // of each instruction: 1 with OE set, the other without. For an + // example see 'add' and 'addo'. + 31: decode XO_XO { + + // These instructions can all be reduced to the form + // Rt = src1 + src2 [+ CA], therefore we just give src1 and src2 + // (and, if necessary, CA) definitions and let the python script + // deal with setting things up correctly. We also give flags to + // say which control registers to set. + format IntSumOp { + 266: add({{ Ra }}, {{ Rb }}); + 40: subf({{ ~Ra }}, {{ Rb }}, {{ 1 }}); + 10: addc({{ Ra }}, {{ Rb }}, + computeCA = true); + 8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }}, + true); + 104: neg({{ ~Ra }}, {{ 1 }}); + 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }}, + true); + 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, + true); + 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }}, + true); + 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, + true); + 202: addze({{ Ra }}, {{ xer.ca }}, + computeCA = true); + 200: subfze({{ ~Ra }}, {{ xer.ca }}, + computeCA = true); + } + + // Arithmetic instructions all use source registers Ra and Rb, + // with destination register Rt. + format IntArithOp { + 75: mulhw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod >> 32; }}); + 11: mulhwu({{ uint64_t prod = Ra.uq * Rb.uq; Rt = prod >> 32; }}); + 235: mullw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod; }}); + 747: mullwo({{ int64_t src1 = Ra.sq; int64_t src2 = Rb; int64_t prod = src1 * src2; Rt = prod; }}, + true); + + 491: divw({{ + int32_t src1 = Ra.sw; + int32_t src2 = Rb.sw; + if ((src1 != 0x80000000 || src2 != 0xffffffff) + && src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + } + }}); + + 1003: divwo({{ + int32_t src1 = Ra.sw; + int32_t src2 = Rb.sw; + if ((src1 != 0x80000000 || src2 != 0xffffffff) + && src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + divSetOV = true; + } + }}, + true); + + 459: divwu({{ + uint32_t src1 = Ra.sw; + uint32_t src2 = Rb.sw; + if (src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + } + }}); + + 971: divwuo({{ + uint32_t src1 = Ra.sw; + uint32_t src2 = Rb.sw; + if (src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + divSetOV = true; + } + }}, + true); + } + + // Integer logic instructions use source registers Rs and Rb, + // with destination register Ra. + format IntLogicOp { + 28: and({{ Ra = Rs & Rb; }}); + 316: xor({{ Ra = Rs ^ Rb; }}); + 476: nand({{ Ra = ~(Rs & Rb); }}); + 444: or({{ Ra = Rs | Rb; }}); + 124: nor({{ Ra = ~(Rs | Rb); }}); + 60: andc({{ Ra = Rs & ~Rb; }}); + 954: extsb({{ Ra = sext<8>(Rs); }}); + 284: eqv({{ Ra = ~(Rs ^ Rb); }}); + 412: orc({{ Ra = Rs | ~Rb; }}); + 922: extsh({{ Ra = sext<16>(Rs); }}); + 26: cntlzw({{ Ra = Rs == 0 ? 32 : 31 - findMsbSet(Rs); }}); + 508: cmpb({{ + uint32_t val = 0; + for (int n = 0; n < 32; n += 8) { + if(bits(Rs, n, n+7) == bits(Rb, n, n+7)) { + val = insertBits(val, n, n+7, 0xff); + } + } + Ra = val; + }}); + + 24: slw({{ + if (Rb & 0x20) { + Ra = 0; + } else { + Ra = Rs << (Rb & 0x1f); + } + }}); + + 536: srw({{ + if (Rb & 0x20) { + Ra = 0; + } else { + Ra = Rs >> (Rb & 0x1f); + } + }}); + + 792: sraw({{ + bool shiftSetCA = false; + int32_t s = Rs; + if (Rb == 0) { + Ra = Rs; + shiftSetCA = true; + } else if (Rb & 0x20) { + if (s < 0) { + Ra = (uint32_t)-1; + if (s & 0x7fffffff) { + shiftSetCA = true; + } else { + shiftSetCA = false; + } + } else { + Ra = 0; + shiftSetCA = false; + } + } else { + Ra = s >> (Rb & 0x1f); + if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) { + shiftSetCA = true; + } else { + shiftSetCA = false; + } + } + Xer xer1 = XER; + if (shiftSetCA) { + xer1.ca = 1; + } else { + xer1.ca = 0; + } + XER = xer1; + }}); + } + + // Integer logic instructions with a shift value. + format IntShiftOp { + 824: srawi({{ + bool shiftSetCA = false; + if (sh == 0) { + Ra = Rs; + shiftSetCA = false; + } else { + int32_t s = Rs; + Ra = s >> sh; + if (s < 0 && (s << (32 - sh)) != 0) { + shiftSetCA = true; + } else { + shiftSetCA = false; + } + } + Xer xer1 = XER; + if (shiftSetCA) { + xer1.ca = 1; + } else { + xer1.ca = 0; + } + XER = xer1; + }}); + } + + // Generic integer format instructions. + format IntOp { + 0: cmp({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra.sw, Rb.sw, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + 32: cmpl({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra, Rb, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + 144: mtcrf({{ + uint32_t mask = 0; + for (int i = 0; i < 8; ++i) { + if (((FXM >> i) & 0x1) == 0x1) { + mask |= 0xf << (4 * i); + } + } + CR = (Rs & mask) | (CR & ~mask); + }}); + 19: mfcr({{ Rt = CR; }}); + 339: decode SPR { + 0x20: mfxer({{ Rt = XER; }}); + 0x100: mflr({{ Rt = LR; }}); + 0x120: mfctr({{ Rt = CTR; }}); + } + 467: decode SPR { + 0x20: mtxer({{ XER = Rs; }}); + 0x100: mtlr({{ LR = Rs; }}); + 0x120: mtctr({{ CTR = Rs; }}); + } + } + + // All loads with an index register. The non-update versions + // all use the value 0 if Ra == R0, not the value contained in + // R0. Others update Ra with the effective address. In all cases, + // Ra and Rb are source registers, Rt is the destintation. + format LoadIndexOp { + 87: lbzx({{ Rt = Mem.ub; }}); + 279: lhzx({{ Rt = Mem.uh; }}); + 343: lhax({{ Rt = Mem.sh; }}); + 23: lwzx({{ Rt = Mem; }}); + 341: lwax({{ Rt = Mem.sw; }}); + 20: lwarx({{ Rt = Mem.sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); + 535: lfsx({{ Ft.sf = Mem.sf; }}); + 599: lfdx({{ Ft = Mem.df; }}); + 855: lfiwax({{ Ft.uw = Mem; }}); + } + + format LoadIndexUpdateOp { + 119: lbzux({{ Rt = Mem.ub; }}); + 311: lhzux({{ Rt = Mem.uh; }}); + 375: lhaux({{ Rt = Mem.sh; }}); + 55: lwzux({{ Rt = Mem; }}); + 373: lwaux({{ Rt = Mem.sw; }}); + 567: lfsux({{ Ft.sf = Mem.sf; }}); + 631: lfdux({{ Ft = Mem.df; }}); + } + + format StoreIndexOp { + 215: stbx({{ Mem.ub = Rs.ub; }}); + 407: sthx({{ Mem.uh = Rs.uh; }}); + 151: stwx({{ Mem = Rs; }}); + 150: stwcx({{ + bool store_performed = false; + if (Rsv) { + if (RsvLen == 4) { + if (RsvAddr == EA) { + Mem = Rs; + store_performed = true; + } + } + } + Xer xer = XER; + Cr cr = CR; + cr.cr0 = ((store_performed ? 0x2 : 0x0) | xer.so); + CR = cr; + Rsv = 0; + }}); + 663: stfsx({{ Mem.sf = Fs.sf; }}); + 727: stfdx({{ Mem.df = Fs; }}); + 983: stfiwx({{ Mem = Fs.uw; }}); + } + + format StoreIndexUpdateOp { + 247: stbux({{ Mem.ub = Rs.ub; }}); + 439: sthux({{ Mem.uh = Rs.uh; }}); + 183: stwux({{ Mem = Rs; }}); + 695: stfsux({{ Mem.sf = Fs.sf; }}); + 759: stfdux({{ Mem.df = Fs; }}); + } + + // These instructions all provide data cache hints + format MiscOp { + 278: dcbt({{ }}); + 246: dcbtst({{ }}); + 598: sync({{ }}, [ IsMemBarrier ]); + 854: eieio({{ }}, [ IsMemBarrier ]); + } + } + + format IntImmArithCheckRaOp { + 14: addi({{ Rt = Ra + imm; }}, + {{ Rt = imm }}); + 15: addis({{ Rt = Ra + (imm << 16); }}, + {{ Rt = imm << 16; }}); + } + + format IntImmArithOp { + 12: addic({{ uint32_t src = Ra; Rt = src + imm; }}, + [computeCA]); + 13: addic_({{ uint32_t src = Ra; Rt = src + imm; }}, + [computeCA, computeCR0]); + 8: subfic({{ int32_t src = ~Ra; Rt = src + imm + 1; }}, + [computeCA]); + 7: mulli({{ + int32_t src = Ra.sw; + int64_t prod = src * imm; + Rt = (uint32_t)prod; + }}); + } + + format IntImmLogicOp { + 24: ori({{ Ra = Rs | uimm; }}); + 25: oris({{ Ra = Rs | (uimm << 16); }}); + 26: xori({{ Ra = Rs ^ uimm; }}); + 27: xoris({{ Ra = Rs ^ (uimm << 16); }}); + 28: andi_({{ Ra = Rs & uimm; }}, + true); + 29: andis_({{ Ra = Rs & (uimm << 16); }}, + true); + } + + 16: decode AA { + + // Conditionally branch relative to PC based on CR and CTR. + format BranchPCRelCondCtr { + 0: bc({{ NPC = PC + disp; }}); + } + + // Conditionally branch to fixed address based on CR and CTR. + format BranchNonPCRelCondCtr { + 1: bca({{ NPC = targetAddr; }}); + } + } + + 18: decode AA { + + // Unconditionally branch relative to PC. + format BranchPCRel { + 0: b({{ NPC = PC + disp; }}); + } + + // Unconditionally branch to fixed address. + format BranchNonPCRel { + 1: ba({{ NPC = targetAddr; }}); + } + } + + 19: decode XO_XO { + + // Conditionally branch to address in LR based on CR and CTR. + format BranchLrCondCtr { + 16: bclr({{ NPC = LR & 0xfffffffc; }}); + } + + // Conditionally branch to address in CTR based on CR. + format BranchCtrCond { + 528: bcctr({{ NPC = CTR & 0xfffffffc; }}); + } + + // Condition register manipulation instructions. + format CondLogicOp { + 257: crand({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa & crBb); + }}); + 449: cror({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa | crBb); + }}); + 255: crnand({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, !(crBa & crBb)); + }}); + 193: crxor({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa ^ crBb); + }}); + 33: crnor({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, !(crBa | crBb)); + }}); + 289: creqv({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa == crBb); + }}); + 129: crandc({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa & !crBb); + }}); + 417: crorc({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa | !crBb); + }}); + } + format CondMoveOp { + 0: mcrf({{ + uint32_t crBfa = bits(CR, 31 - bfa*4, 28 - bfa*4); + CR = insertBits(CR, 31 - bf*4, 28 - bf*4, crBfa); + }}); + } + format MiscOp { + 150: isync({{ }}, [ IsSerializeAfter ]); + } + } + + format IntRotateOp { + 21: rlwinm({{ Ra = rotateValue(Rs, sh) & fullMask; }}); + 23: rlwnm({{ Ra = rotateValue(Rs, Rb) & fullMask; }}); + 20: rlwimi({{ Ra = (rotateValue(Rs, sh) & fullMask) | (Ra & ~fullMask); }}); + } + + format LoadDispOp { + 34: lbz({{ Rt = Mem.ub; }}); + 40: lhz({{ Rt = Mem.uh; }}); + 42: lha({{ Rt = Mem.sh; }}); + 32: lwz({{ Rt = Mem; }}); + 58: lwa({{ Rt = Mem.sw; }}, + {{ EA = Ra + (disp & 0xfffffffc); }}, + {{ EA = disp & 0xfffffffc; }}); + 48: lfs({{ Ft.sf = Mem.sf; }}); + 50: lfd({{ Ft = Mem.df; }}); + } + + format LoadDispUpdateOp { + 35: lbzu({{ Rt = Mem.ub; }}); + 41: lhzu({{ Rt = Mem.uh; }}); + 43: lhau({{ Rt = Mem.sh; }}); + 33: lwzu({{ Rt = Mem; }}); + 49: lfsu({{ Ft.sf = Mem.sf; }}); + 51: lfdu({{ Ft = Mem.df; }}); + } + + format StoreDispOp { + 38: stb({{ Mem.ub = Rs.ub; }}); + 44: sth({{ Mem.uh = Rs.uh; }}); + 36: stw({{ Mem = Rs; }}); + 52: stfs({{ Mem.sf = Fs.sf; }}); + 54: stfd({{ Mem.df = Fs; }}); + } + + format StoreDispUpdateOp { + 39: stbu({{ Mem.ub = Rs.ub; }}); + 45: sthu({{ Mem.uh = Rs.uh; }}); + 37: stwu({{ Mem = Rs; }}); + 53: stfsu({{ Mem.sf = Fs.sf; }}); + 55: stfdu({{ Mem.df = Fs; }}); + } + + 17: IntOp::sc({{ xc->syscall(R0); }}, + [ IsSyscall, IsNonSpeculative, IsSerializeAfter ]); + + format FloatArithOp { + 59: decode A_XO { + 21: fadds({{ Ft = Fa + Fb; }}); + 20: fsubs({{ Ft = Fa - Fb; }}); + 25: fmuls({{ Ft = Fa * Fc; }}); + 18: fdivs({{ Ft = Fa / Fb; }}); + 29: fmadds({{ Ft = (Fa * Fc) + Fb; }}); + 28: fmsubs({{ Ft = (Fa * Fc) - Fb; }}); + 31: fnmadds({{ Ft = -((Fa * Fc) + Fb); }}); + 30: fnmsubs({{ Ft = -((Fa * Fc) - Fb); }}); + } + } + + 63: decode A_XO { + format FloatArithOp { + 21: fadd({{ Ft = Fa + Fb; }}); + 20: fsub({{ Ft = Fa - Fb; }}); + 25: fmul({{ Ft = Fa * Fc; }}); + 18: fdiv({{ Ft = Fa / Fb; }}); + 29: fmadd({{ Ft = (Fa * Fc) + Fb; }}); + 28: fmsub({{ Ft = (Fa * Fc) - Fb; }}); + 31: fnmadd({{ Ft = -((Fa * Fc) + Fb); }}); + 30: fnmsub({{ Ft = -((Fa * Fc) - Fb); }}); + } + + default: decode XO_XO { + format FloatConvertOp { + 12: frsp({{ Ft.sf = Fb; }}); + 15: fctiwz({{ Ft.sw = (int32_t)trunc(Fb); }}); + } + + format FloatOp { + 0: fcmpu({{ + uint32_t c = makeCRField(Fa, Fb); + Fpscr fpscr = FPSCR; + fpscr.fprf.fpcc = c; + FPSCR = fpscr; + CR = insertCRField(CR, BF, c); + }}); + } + + format FloatRCCheckOp { + 72: fmr({{ Ft = Fb; }}); + 264: fabs({{ + Ft.uq = Fb.uq; + Ft.uq = insertBits(Ft.uq, 63, 0); }}); + 136: fnabs({{ + Ft.uq = Fb.uq; + Ft.uq = insertBits(Ft.uq, 63, 1); }}); + 40: fneg({{ Ft = -Fb; }}); + 8: fcpsgn({{ + Ft.uq = Fb.uq; + Ft.uq = insertBits(Ft.uq, 63, Fa.uq<63:63>); + }}); + 583: mffs({{ Ft.uq = FPSCR; }}); + 134: mtfsfi({{ + FPSCR = insertCRField(FPSCR, BF + (8 * (1 - W)), U_FIELD); + }}); + 711: mtfsf({{ + if (L == 1) { FPSCR = Fb.uq; } + else { + for (int i = 0; i < 8; ++i) { + if (bits(FLM, i) == 1) { + int k = 4 * (i + (8 * (1 - W))); + FPSCR = insertBits(FPSCR, k, k + 3, + bits(Fb.uq, k, k + 3)); + } + } + } + }}); + 70: mtfsb0({{ FPSCR = insertBits(FPSCR, 31 - BT, 0); }}); + 38: mtfsb1({{ FPSCR = insertBits(FPSCR, 31 - BT, 1); }}); + } + } + } +} diff --git a/src/arch/power/isa/formats/basic.isa b/src/arch/power/isa/formats/basic.isa new file mode 100644 index 000000000..adb5e7ef8 --- /dev/null +++ b/src/arch/power/isa/formats/basic.isa @@ -0,0 +1,103 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +// Declarations for execute() methods. +def template BasicExecDeclare {{ + Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + +// Basic instruction class declaration template. +def template BasicDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + /// Constructor. + %(class_name)s(ExtMachInst machInst); + %(BasicExecDeclare)s + }; +}}; + +// Basic instruction class constructor template. +def template BasicConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + + +// Basic instruction class execute method template. +def template BasicExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == NoFault) + { + %(op_wb)s; + } + + return fault; + } +}}; + +// Basic decode template. +def template BasicDecode {{ + return new %(class_name)s(machInst); +}}; + +// Basic decode template, passing mnemonic in as string arg to constructor. +def template BasicDecodeWithMnemonic {{ + return new %(class_name)s("%(mnemonic)s", machInst); +}}; + +// Definitions of execute methods that panic. +def template BasicExecPanic {{ +Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const +{ + panic("Execute method called when it shouldn't!"); +} +}}; + +// The most basic instruction format... +def format BasicOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'PowerStaticInst', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/power/isa/formats/branch.isa b/src/arch/power/isa/formats/branch.isa new file mode 100644 index 000000000..d51ed5c25 --- /dev/null +++ b/src/arch/power/isa/formats/branch.isa @@ -0,0 +1,222 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Control transfer instructions +// +// From the Power ISA Book I v2.06, page 33, the following rules should +// be obeyed by programmers: +// +// - Use branch instructions where LK == 1 only as subroutine calls. +// - Pair each subroutine call with a bclr instruction with BH == 00 +// that returns from the subroutine. +// - Do not use bclrl as a subroutine call. +// +// Therefore, I've flagged all versions that update the link register (LR) +// as calls, except bclrl (BranchLrCtrCond format) which is flagged as +// a return. + + +let {{ + +# Simple code to update link register (LR). +updateLrCode = 'LR = PC + 4;' + +}}; + +// Instructions that unconditionally branch relative to the current PC. +def format BranchPCRel(br_code, inst_flags = []) {{ + inst_flags += ('IsUncondControl', 'IsDirectControl') + basic_code = br_code + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchPCRel', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchPCRel', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that unconditionally branch to a specific address. +def format BranchNonPCRel(br_code, inst_flags = []) {{ + inst_flags += ('IsUncondControl', 'IsDirectControl') + basic_code = br_code + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchNonPCRel', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRel', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +let {{ + +# Check the condition register (CR) allows the branch to be taken. +def GetCondCode(br_code): + cond_code = 'if(condOk(CR)) {\n' + cond_code += ' ' + br_code + '\n' + cond_code += '} else {\n' + cond_code += ' NPC = NPC;\n' + cond_code += '}\n' + return cond_code + +# Check the condition register (CR) and count register (CTR) allow the +# branch to be taken. Also, in certain situations, decrement the count +# register too. This takes place in ctrOk within BranchCond classes. +def GetCtrCondCode(br_code): + cond_code = 'uint32_t ctr = CTR;\n' + cond_code += 'bool ctr_ok = ctrOk(ctr);\n' + cond_code += 'bool cond_ok = condOk(CR);\n' + cond_code += 'if(ctr_ok && cond_ok) {\n' + cond_code += ' ' + br_code + '\n' + cond_code += '} else {\n' + cond_code += ' NPC = NPC;\n' + cond_code += '}\n' + cond_code += 'CTR = ctr;\n' + return cond_code + +}}; + +// Instructions that conditionally branch relative to the current PC based on +// the condition register (CR) and count register (CTR). +def format BranchPCRelCondCtr(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsDirectControl') + basic_code = GetCtrCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchPCRelCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchPCRelCond', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that conditionally branch to a specific address based on the +// condition register (CR) and count register (CTR). +def format BranchNonPCRelCondCtr(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsDirectControl') + basic_code = GetCtrCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchNonPCRelCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRelCond', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that conditionally branch to the address in the link register +// (LR) based on the condition register (CR) and count register (CTR). +def format BranchLrCondCtr(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsIndirectControl', 'IsReturn') + basic_code = GetCtrCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code, + inst_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that conditionally branch to the address in the count register +// (CTR) based on the condition register (CR). +def format BranchCtrCond(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsIndirectControl') + basic_code = GetCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; diff --git a/src/arch/power/isa/formats/condition.isa b/src/arch/power/isa/formats/condition.isa new file mode 100644 index 000000000..12ee7ae7d --- /dev/null +++ b/src/arch/power/isa/formats/condition.isa @@ -0,0 +1,47 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +// Logical instructions that manipulate the condition register +def format CondLogicOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'CondLogicOp', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +// Instructions that condition register fields +def format CondMoveOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'CondMoveOp', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/power/isa/formats/formats.isa b/src/arch/power/isa/formats/formats.isa new file mode 100644 index 000000000..ec2575196 --- /dev/null +++ b/src/arch/power/isa/formats/formats.isa @@ -0,0 +1,60 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//Templates from this format are used later +//Include the basic format +##include "basic.isa" + +//Include integer instructions +##include "integer.isa" + +//Include condition register instructions +##include "condition.isa" + +//Include utility functions +##include "util.isa" + +//Include the float formats +##include "fp.isa" + +//Include the mem format +##include "mem.isa" + +//Include the branch format +##include "branch.isa" + +//Include the misc format +##include "misc.isa" + +//Include the unimplemented format +##include "unimp.isa" + +//Include the unknown format +##include "unknown.isa" diff --git a/src/arch/power/isa/formats/fp.isa b/src/arch/power/isa/formats/fp.isa new file mode 100644 index 000000000..db917476e --- /dev/null +++ b/src/arch/power/isa/formats/fp.isa @@ -0,0 +1,132 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Floating Point operate instructions +// + + +let {{ + + readFPSCRCode = 'Fpscr fpscr = FPSCR;' + + computeCR1Code = ''' + Cr cr = CR; + cr.cr1 = (fpscr.fx << 3) | (fpscr.fex << 2) | + (fpscr.vx << 1) | fpscr.ox; + CR = cr; + ''' + +}}; + +// Primary format for floating point operate instructions: +def format FloatOp(code, inst_flags = []) {{ + iop = InstObjParams(name, Name, 'FloatOp', + {"code": code}, + inst_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +// Floating point operations that compute the CR1 code if RC is set. No other +// special registers are touched using these operations. +def format FloatRCCheckOp(code, inst_flags = []) {{ + + # Code when Rc is set + code_rc1 = code + readFPSCRCode + computeCR1Code + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'FloatOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + +// Floating point elementary arithmetic operations. Besides having two +// versions of each instruction for when Rc is set or not, we also have +// to alter lots of special registers depending on the result of the +// operation. The result is always in Ft.sf. +def format FloatArithOp(code, inst_flags = []) {{ + + # Code when Rc is set + code_rc1 = code + readFPSCRCode + computeCR1Code + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'FloatOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + +// Floating point rounding and conversion operations. Besides having two +// versions of each instruction for when Rc is set or not, we also have +// to alter lots of special registers depending on the result of the +// operation. The result is always in Ft.sf. +def format FloatConvertOp(code, inst_flags = []) {{ + + # Code when Rc is set + code_rc1 = code + readFPSCRCode + computeCR1Code + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'FloatOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa new file mode 100644 index 000000000..0766826ec --- /dev/null +++ b/src/arch/power/isa/formats/integer.isa @@ -0,0 +1,369 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Integer ALU instructions +// + + +// Instruction class constructor template when Rc is set. +def template IntRcConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + rcSet = true; + } +}}; + + +// Instruction class constructor template when OE is set. +def template IntOeConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + oeSet = true; + } +}}; + + +// Instruction class constructor template when both Rc and OE are set. +def template IntRcOeConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + rcSet = true; + oeSet = true; + } +}}; + + +let {{ + +readXERCode = 'Xer xer = XER;' + +setXERCode = 'XER = xer;' + +computeCR0Code = ''' + Cr cr = CR; + cr.cr0 = makeCRField((int32_t)%(result)s, (int32_t)0, xer.so); + CR = cr; +''' + +computeCACode = ''' + if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ca = 1; + } else { + xer.ca = 0; + } +''' + +computeOVCode = ''' + if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ov = 1; + xer.so = 1; + } else { + xer.ov = 0; + } +''' + +computeDivOVCode = ''' + if (divSetOV) { + xer.ov = 1; + xer.so = 1; + } else { + if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ov = 1; + xer.so = 1; + } else { + xer.ov = 0; + } + } +''' + +}}; + + +// A basic integer instruction. +def format IntOp(code, inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions with immediate (signed or unsigned). +def format IntImmOp(code, inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions with immediate that perform arithmetic. +// These instructions all write to Rt and use an altered form of the +// value in source register Ra, hence the use of src to hold the actual +// value. The control flags include the use of code to compute the +// carry bit or the CR0 code. +def format IntImmArithOp(code, ctrl_flags = [], inst_flags = []) {{ + + # Set up the dictionary and deal with control flags + dict = {'result':'Rt', 'inputa':'src', 'inputb':'imm'} + if ctrl_flags: + code += readXERCode + for val in ctrl_flags: + if val == 'computeCA': + code += computeCACode % dict + setXERCode + elif val == 'computeCR0': + code += computeCR0Code % dict + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions with immediate that perform arithmetic but use +// the value 0 when Ra == 0. We generate two versions of each instruction +// corresponding to these two different scenarios. The correct version is +// determined at decode (see the CheckRaDecode template). +def format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{ + + # First the version where Ra is non-zero + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, + CheckRaDecode, BasicConstructor) + + # Now another version where Ra == 0 + (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ + GenAluOp(name, Name + 'RaZero', 'IntImmOp', code_ra0, inst_flags, + CheckRaDecode, BasicConstructor) + + # Finally, add to the other outputs + header_output += header_output_ra0 + decoder_output += decoder_output_ra0 + exec_output += exec_output_ra0 +}}; + + +// Integer instructions with immediate that perform logic operations. +// All instructions write to Ra and use Rs as a source register. Some +// also compute the CR0 code too. +def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{ + + # Set up the dictionary and deal with computing CR0 + dict = {'result':'Ra'} + if computeCR0: + code += readXERCode + computeCR0Code % dict + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions that perform logic operations. The result is +// always written into Ra. All instructions have 2 versions depending on +// whether the Rc bit is set to compute the CR0 code. This is determined +// at decode as before. +def format IntLogicOp(code, inst_flags = []) {{ + dict = {'result':'Ra'} + + # Code when Rc is set + code_rc1 = code + readXERCode + computeCR0Code % dict + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + + +// Integer instructions with a shift amount. As above, except inheriting +// from the IntShiftOp class. +def format IntShiftOp(code, inst_flags = []) {{ + dict = {'result':'Ra'} + + # Code when Rc is set + code_rc1 = code + readXERCode + computeCR0Code % dict + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntShiftOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + + +// Instructions in this format are all reduced to the form Rt = src1 + src2, +// therefore we just give src1 and src2 definitions. In working out the +// template we first put in the definitions of the variables and then +// the code for the addition. We also deal with computing the carry flag +// if required. +// +// We generate 4 versions of each instruction. This correspond to the +// different combinations of having the OE bit set or unset (which controls +// whether the overflow flag is computed) and the Rc bit set or unset too +// (which controls whether the CR0 code is computed). +def format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0, + inst_flags = []) {{ + + # The result is always in Rt, but the source values vary + dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'} + + # Add code to set up variables and do the sum + code = 'uint32_t src1 = ' + src1 + ';\n' + code += 'uint32_t src2 = ' + src2 + ';\n' + code += 'uint32_t ca = ' + ca + ';\n' + code += 'Rt = src1 + src2 + ca;\n' + + # Add code for calculating the carry, if needed + if computeCA: + code += computeCACode % dict + setXERCode + + # Setup the 4 code versions and add code to access XER if necessary + code_rc1 = readXERCode + code + code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode + code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode + if (computeCA or ca == 'xer.ca'): + code = readXERCode + code + code_rc1 += computeCR0Code % dict + code_rc1_oe1 += computeCR0Code % dict + + # Generate the classes + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, + CheckRcOeDecode, BasicConstructor) + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, + CheckRcOeDecode, IntRcConstructor) + (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \ + GenAluOp(name, Name + 'OeSet', 'IntOp', code_oe1, inst_flags, + CheckRcOeDecode, IntOeConstructor) + (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \ + GenAluOp(name, Name + 'RcSetOeSet', 'IntOp', code_rc1_oe1, + inst_flags, CheckRcOeDecode, IntRcOeConstructor) + + # Finally, add to the other outputs + header_output += \ + header_output_rc1 + header_output_oe1 + header_output_rc1_oe1 + decoder_output += \ + decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1 + exec_output += \ + exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1 + +}}; + + +// Instructions that use source registers Ra and Rb, with the result +// placed into Rt. Basically multiply and divide instructions. The +// carry bit is never set, but overflow can be calculated. Division +// explicitly sets the overflow bit in certain situations and this is +// dealt with using the 'divSetOV' boolean in decoder.isa. We generate +// two versions of each instruction to deal with the Rc bit. +def format IntArithOp(code, computeOV = 0, inst_flags = []) {{ + + # The result is always in Rt, but the source values vary + dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'} + + # Deal with setting the overflow flag + if computeOV: + code = 'bool divSetOV = false;\n' + code + code += computeDivOVCode % dict + setXERCode + + # Setup the 2 code versions and add code to access XER if necessary + code_rc1 = readXERCode + code + computeCR0Code % dict + if computeOV: + code = readXERCode + code + + # Generate the classes + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + + +// A special format for rotate instructions which use certain fields +// from the instruction's binary encoding. We need two versions for each +// instruction to deal with the Rc bit. +def format IntRotateOp(code, inst_flags = []) {{ + + # The result is always in Ra + dict = {'result':'Ra'} + + # Setup the code for when Rc is set + code_rc1 = readXERCode + code + computeCR0Code % dict + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntRotateOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa new file mode 100644 index 000000000..1be49c2f7 --- /dev/null +++ b/src/arch/power/isa/formats/mem.isa @@ -0,0 +1,351 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Memory-format instructions +// + +def template LoadStoreDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + + /// Constructor. + %(class_name)s(ExtMachInst machInst); + + %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s + }; +}}; + + +def template InitiateAccDeclare {{ + Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template CompleteAccDeclare {{ + Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template LoadStoreConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + + +def template LoadExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template LoadInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_src_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); + xc->setEA(EA); + } + + return fault; + } +}}; + + +def template LoadCompleteAcc {{ + Fault %(class_name)s::completeAcc(PacketPtr pkt, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + uint%(mem_acc_size)d_t val; + + %(op_decl)s; + %(op_rd)s; + + EA = xc->getEA(); + + val = pkt->get<uint%(mem_acc_size)d_t>(); + *((uint%(mem_acc_size)d_t*)&Mem) = val; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, NULL); + if (traceData) { traceData->setData(Mem); } + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, NULL); + if (traceData) { traceData->setData(Mem); } + } + + // Need to write back any potential address register update + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreCompleteAcc {{ + Fault %(class_name)s::completeAcc(PacketPtr pkt, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(op_dest_decl)s; + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +// The generic memory operation generator. This is called when two versions +// of an instruction are needed - when Ra == 0 and otherwise. This is so +// that instructions can use the value 0 when Ra == 0 but avoid having a +// dependence on Ra. +let {{ + +def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, + load_or_store, mem_flags = [], inst_flags = []): + + # First the version where Ra is non-zero + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = base, + decode_template = CheckRaDecode, + exec_template_base = load_or_store) + + # Now another version where Ra == 0 + (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ + LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, + mem_flags, inst_flags, + base_class = base, + exec_template_base = load_or_store) + + # Finally, add to the other outputs + header_output += header_output_ra0 + decoder_output += decoder_output_ra0 + exec_output += exec_output_ra0 + return (header_output, decoder_output, decode_block, exec_output) + +}}; + + +def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + ea_code_ra0 = {{ EA = Rb; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemOp', 'Load', mem_flags, inst_flags) +}}; + + +def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + ea_code_ra0 = {{ EA = Rb; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemOp', 'Store', mem_flags, inst_flags) +}}; + + +def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemOp', + exec_template_base = 'Load') +}}; + + +def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemOp', + exec_template_base = 'Store') +}}; + + +def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + ea_code_ra0 = {{ EA = disp; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemDispOp', 'Load', mem_flags, inst_flags) +}}; + + +def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + ea_code_ra0 = {{ EA = disp; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemDispOp', 'Store', mem_flags, inst_flags) +}}; + + +def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemDispOp', + exec_template_base = 'Load') +}}; + + +def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemDispOp', + exec_template_base = 'Store') +}}; diff --git a/src/arch/power/isa/formats/misc.isa b/src/arch/power/isa/formats/misc.isa new file mode 100644 index 000000000..93536aa18 --- /dev/null +++ b/src/arch/power/isa/formats/misc.isa @@ -0,0 +1,61 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Misc instructions +// + +def template MiscOpExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + %(op_decl)s; + %(op_rd)s; + + %(code)s; + if (fault == NoFault) + { + %(op_wb)s; + } + + return fault; + } +}}; + +def format MiscOp(code, opt_flags = []) {{ + iop = InstObjParams(name, Name, 'IntOp', + {"code": code}, + opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = MiscOpExecute.subst(iop) +}}; diff --git a/src/arch/power/isa/formats/unimp.isa b/src/arch/power/isa/formats/unimp.isa new file mode 100644 index 000000000..60a7c469d --- /dev/null +++ b/src/arch/power/isa/formats/unimp.isa @@ -0,0 +1,146 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2007-2008 The Florida State University +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Stephen Hines +// Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Unimplemented instructions +// + +output header {{ + /** + * Static instruction class for unimplemented instructions that + * cause simulator termination. Note that these are recognized + * (legal) instructions that the simulator does not support; the + * 'Unknown' class is used for unrecognized/illegal instructions. + * This is a leaf class. + */ + class FailUnimplemented : public PowerStaticInst + { + public: + /// Constructor + FailUnimplemented(const char *_mnemonic, MachInst _machInst) + : PowerStaticInst(_mnemonic, _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for unimplemented instructions that cause a warning + * to be printed (but do not terminate simulation). This + * implementation is a little screwy in that it will print a + * warning for each instance of a particular unimplemented machine + * instruction, not just for each unimplemented opcode. Should + * probably make the 'warned' flag a static member of the derived + * class. + */ + class WarnUnimplemented : public PowerStaticInst + { + private: + /// Have we warned on this instruction yet? + mutable bool warned; + + public: + /// Constructor + WarnUnimplemented(const char *_mnemonic, MachInst _machInst) + : PowerStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + FailUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } + + std::string + WarnUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } +}}; + +output exec {{ + Fault + FailUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE, + inst2string(machInst)); + return new UnimplementedOpcodeFault; + } + + Fault + WarnUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (!warned) { + warn("\tinstruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return NoFault; + } +}}; + + +def format FailUnimpl() {{ + iop = InstObjParams(name, 'FailUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +def format WarnUnimpl() {{ + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + diff --git a/src/arch/power/isa/formats/unknown.isa b/src/arch/power/isa/formats/unknown.isa new file mode 100644 index 000000000..06e6ece26 --- /dev/null +++ b/src/arch/power/isa/formats/unknown.isa @@ -0,0 +1,87 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2007-2008 The Florida State University +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Stephen Hines +// Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Unknown instructions +// + +output header {{ + /** + * Static instruction class for unknown (illegal) instructions. + * These cause simulator termination if they are executed in a + * non-speculative mode. This is a leaf class. + */ + class Unknown : public PowerStaticInst + { + public: + /// Constructor + Unknown(ExtMachInst _machInst) + : PowerStaticInst("unknown", _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)", + "unknown", machInst, OPCODE, inst2string(machInst)); + } +}}; + +output exec {{ + Fault + Unknown::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unknown instruction at %#x" + "(inst 0x%08x, opcode 0x%x, binary: %s)", + xc->readPC(), machInst, OPCODE, inst2string(machInst)); + return new UnimplementedOpcodeFault; + } +}}; + +def format Unknown() {{ + decode_block = 'return new Unknown(machInst);\n' +}}; + diff --git a/src/arch/power/isa/formats/util.isa b/src/arch/power/isa/formats/util.isa new file mode 100644 index 000000000..ab1e530b2 --- /dev/null +++ b/src/arch/power/isa/formats/util.isa @@ -0,0 +1,174 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2005 The Regents of The University of Michigan +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Steve Reinhardt +// Korey Sewell +// Timothy M. Jones + +// Some instructions ignore the contents of Ra if Ra == 0, +// so check for this. +def template CheckRaDecode {{ + { + if (RA == 0) { + return new %(class_name)sRaZero(machInst); + } else { + return new %(class_name)s(machInst); + } + } +}}; + + +// Some instructions have extra behaviour if Rc is set. +def template CheckRcDecode {{ + { + if (RC31 == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sRcSet(machInst); + } + } +}}; + + +// Some instructions have extra behaviour if Rc and OE are set. +def template CheckRcOeDecode {{ + { + if (RC31 == 0) { + if (OE == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sOeSet(machInst); + } + } else { + if (OE == 0) { + return new %(class_name)sRcSet(machInst); + } else { + return new %(class_name)sRcSetOeSet(machInst); + } + } + } +}}; + +// Branch instructions always have two versions, one which sets the link +// register (LR). +def template CheckLkDecode {{ + { + if (LK == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sUpdateLr(machInst); + } + } +}}; + + +let {{ + +def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemOp', + decode_template = BasicDecode, exec_template_base = ''): + # Make sure flags are in lists (convert to lists if not). + mem_flags = makeList(mem_flags) + inst_flags = makeList(inst_flags) + + # add hook to get effective addresses into execution trace output. + ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' + + # Generate InstObjParams for the memory access. + iop = InstObjParams(name, Name, base_class, + {'ea_code': ea_code, + 'memacc_code': memacc_code}, + inst_flags) + + if mem_flags: + s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' + iop.constructor += s + + fullExecTemplate = eval(exec_template_base + 'Execute') + initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') + completeAccTemplate = eval(exec_template_base + 'CompleteAcc') + + # (header_output, decoder_output, decode_block, exec_output) + return (LoadStoreDeclare.subst(iop), + LoadStoreConstructor.subst(iop), + decode_template.subst(iop), + fullExecTemplate.subst(iop) + + initiateAccTemplate.subst(iop) + + completeAccTemplate.subst(iop)) + + +# The generic ALU instruction generator. Integer and fp formats calls this +# to generate the different output sections. +def GenAluOp(name, Name, base_class, code, inst_flags, decode_template, + constructor_template): + iop = InstObjParams(name, Name, base_class, + {"code": code}, + inst_flags) + header_output = BasicDeclare.subst(iop) + exec_output = BasicExecute.subst(iop) + + # We use constructors dependent on the Rc and OE bits being set + decoder_output = constructor_template.subst(iop) + + # The decode block defines which version to use + decode_block = decode_template.subst(iop) + return (header_output, decoder_output, decode_block, exec_output) + +}}; + + +output header {{ + std::string + inst2string(MachInst machInst); +}}; + +output decoder {{ + + std::string + inst2string(MachInst machInst) + { + std::string str = ""; + uint32_t mask = 0x80000000; + + for(int i=0; i < 32; i++) { + if ((machInst & mask) == 0) { + str += "0"; + } else { + str += "1"; + } + + mask = mask >> 1; + } + + return str; + } + +}}; + + diff --git a/src/arch/power/isa/includes.isa b/src/arch/power/isa/includes.isa new file mode 100644 index 000000000..47e8c1411 --- /dev/null +++ b/src/arch/power/isa/includes.isa @@ -0,0 +1,92 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Output include file directives. +// + +output header {{ +#include <sstream> +#include <iostream> +#include <iomanip> + +#include "arch/power/insts/branch.hh" +#include "arch/power/insts/mem.hh" +#include "arch/power/insts/integer.hh" +#include "arch/power/insts/floating.hh" +#include "arch/power/insts/condition.hh" +#include "arch/power/insts/misc.hh" +#include "arch/power/insts/static_inst.hh" +#include "arch/power/isa_traits.hh" +#include "cpu/static_inst.hh" +#include "mem/packet.hh" + +using namespace PowerISA; +}}; + +output decoder {{ +#include <cmath> +#if defined(linux) +#include <fenv.h> +#endif + +#include "arch/power/faults.hh" +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" +#include "base/cprintf.hh" +#include "base/loader/symtab.hh" +#include "cpu/thread_context.hh" + +using namespace PowerISA; +using std::isnan; +}}; + +output exec {{ +#include "arch/power/faults.hh" +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" + +#include <cmath> +#if defined(linux) +#include <fenv.h> +#endif + +#include "base/condcodes.hh" +#include "cpu/base.hh" +#include "cpu/exetrace.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "sim/sim_exit.hh" + +using namespace PowerISA; +using std::isnan; +}}; + diff --git a/src/arch/power/isa/main.isa b/src/arch/power/isa/main.isa new file mode 100644 index 000000000..cce7e39ee --- /dev/null +++ b/src/arch/power/isa/main.isa @@ -0,0 +1,57 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Power ISA description file. +// +//////////////////////////////////////////////////////////////////// + +//Include the C++ include directives +##include "includes.isa" + +//////////////////////////////////////////////////////////////////// +// +// Namespace statement. Everything below this line will be in the +// PowerISAInst namespace. +// +namespace PowerISA; + +//Include the bitfield definitions +##include "bitfields.isa" + +//Include the operand_types and operand definitions +##include "operands.isa" + +//Include the definitions for the instruction formats +##include "formats/formats.isa" + +//Include the decoder definition +##include "decoder.isa" diff --git a/src/arch/power/isa/operands.isa b/src/arch/power/isa/operands.isa new file mode 100644 index 000000000..fc6c32685 --- /dev/null +++ b/src/arch/power/isa/operands.isa @@ -0,0 +1,81 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +def operand_types {{ + 'sb' : ('signed int', 8), + 'ub' : ('unsigned int', 8), + 'sh' : ('signed int', 16), + 'uh' : ('unsigned int', 16), + 'sw' : ('signed int', 32), + 'uw' : ('unsigned int', 32), + 'sq' : ('signed int', 64), + 'uq' : ('unsigned int', 64), + 'sf' : ('float', 32), + 'df' : ('float', 64) +}}; + +def operands {{ + # General Purpose Integer Reg Operands + 'Ra': ('IntReg', 'uw', 'RA', 'IsInteger', 1), + 'Rb': ('IntReg', 'uw', 'RB', 'IsInteger', 2), + 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3), + 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 4), + + # General Purpose Floating Point Reg Operands + 'Fa': ('FloatReg', 'df', 'FRA', 'IsFloating', 1), + 'Fb': ('FloatReg', 'df', 'FRB', 'IsFloating', 2), + 'Fc': ('FloatReg', 'df', 'FRC', 'IsFloating', 3), + 'Fs': ('FloatReg', 'df', 'FRS', 'IsFloating', 4), + 'Ft': ('FloatReg', 'df', 'FRT', 'IsFloating', 5), + + # Memory Operand + 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 8), + + # Program counter and next + 'PC': ('PC', 'uw', None, (None, None, 'IsControl'), 9), + 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 9), + + # Control registers + 'CR': ('IntReg', 'uw', 'INTREG_CR', 'IsInteger', 9), + 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9), + 'CTR': ('IntReg', 'uw', 'INTREG_CTR', 'IsInteger', 9), + 'XER': ('IntReg', 'uw', 'INTREG_XER', 'IsInteger', 9), + + # Setting as IntReg so things are stored as an integer, not double + 'FPSCR': ('IntReg', 'uw', 'INTREG_FPSCR', 'IsFloating', 9), + + # Registers for linked loads and stores + 'Rsv': ('IntReg', 'uw', 'INTREG_RSV', 'IsInteger', 9), + 'RsvLen': ('IntReg', 'uw', 'INTREG_RSV_LEN', 'IsInteger', 9), + 'RsvAddr': ('IntReg', 'uw', 'INTREG_RSV_ADDR', 'IsInteger', 9), + + # Hack for non-full-system syscall emulation + 'R0': ('IntReg', 'uw', '0', None, 1), +}}; diff --git a/src/arch/isa_specific.hh b/src/arch/power/isa_traits.hh index de070bbf9..886c2cb0b 100644 --- a/src/arch/isa_specific.hh +++ b/src/arch/power/isa_traits.hh @@ -1,5 +1,7 @@ /* * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,46 +27,49 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Gabe Black + * Authors: Timothy M. Jones + * Gabe Black + * Stephen Hines */ -#ifndef __ARCH_ISA_SPECIFIC_HH__ -#define __ARCH_ISA_SPECIFIC_HH__ +#ifndef __ARCH_POWER_ISA_TRAITS_HH__ +#define __ARCH_POWER_ISA_TRAITS_HH__ -//This file provides a mechanism for other source code to bring in -//files from the ISA being compiled in. +#include "arch/power/types.hh" +#include "base/types.hh" -//These are constants so you can selectively compile code based on the isa. -//To use them, do something like: -// -//#if THE_ISA == YOUR_FAVORITE_ISA -// conditional_code -//#endif -// -//Note that this is how this file sets up the TheISA macro. +namespace BigEndianGuest {}; -//These macros have numerical values because otherwise the preprocessor -//would treat them as 0 in comparisons. -#define ALPHA_ISA 21064 -#define SPARC_ISA 42 -#define MIPS_ISA 34000 -#define X86_ISA 8086 -#define ARM_ISA 6 +class StaticInstPtr; -//These tell the preprocessor where to find the files of a particular -//ISA, and set the "TheISA" macro for use elsewhere. -#if THE_ISA == ALPHA_ISA - #define TheISA AlphaISA -#elif THE_ISA == SPARC_ISA - #define TheISA SparcISA -#elif THE_ISA == MIPS_ISA - #define TheISA MipsISA -#elif THE_ISA == X86_ISA - #define TheISA X86ISA -#elif THE_ISA == ARM_ISA - #define TheISA ArmISA -#else - #error "THE_ISA not set" -#endif +namespace PowerISA +{ -#endif +using namespace BigEndianGuest; + +StaticInstPtr decodeInst(ExtMachInst); + +// POWER DOES NOT have a delay slot +#define ISA_HAS_DELAY_SLOT 0 + +const Addr PageShift = 12; +const Addr PageBytes = ULL(1) << PageShift; +const Addr Page_Mask = ~(PageBytes - 1); +const Addr PageOffset = PageBytes - 1; + +const Addr PteShift = 3; +const Addr NPtePageShift = PageShift - PteShift; +const Addr NPtePage = ULL(1) << NPtePageShift; +const Addr PteMask = NPtePage - 1; + +const int LogVMPageSize = 12; // 4K bytes +const int VMPageSize = (1 << LogVMPageSize); + +const int MachineBytes = 4; + +// This is ori 0, 0, 0 +const ExtMachInst NoopMachInst = 0x60000000; + +} // PowerISA namespace + +#endif // __ARCH_POWER_ISA_TRAITS_HH__ diff --git a/src/arch/power/linux/linux.cc b/src/arch/power/linux/linux.cc new file mode 100644 index 000000000..113f3e48e --- /dev/null +++ b/src/arch/power/linux/linux.cc @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/linux/linux.hh" + +#include <fcntl.h> + +// open(2) flags translation table +OpenFlagTransTable PowerLinux::openFlagTable[] = { +#ifdef _MSC_VER + { PowerLinux::TGT_O_RDONLY, _O_RDONLY }, + { PowerLinux::TGT_O_WRONLY, _O_WRONLY }, + { PowerLinux::TGT_O_RDWR, _O_RDWR }, + { PowerLinux::TGT_O_APPEND, _O_APPEND }, + { PowerLinux::TGT_O_CREAT, _O_CREAT }, + { PowerLinux::TGT_O_TRUNC, _O_TRUNC }, + { PowerLinux::TGT_O_EXCL, _O_EXCL }, +#ifdef _O_NONBLOCK + { PowerLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, +#endif +#ifdef _O_NOCTTY + { PowerLinux::TGT_O_NOCTTY, _O_NOCTTY }, +#endif +#ifdef _O_SYNC + { PowerLinux::TGT_O_SYNC, _O_SYNC }, +#endif +#ifdef _O_LARGEFILE + { PowerLinux::TGT_O_LARGEFILE, _O_LARGEFILE }, +#endif +#else /* !_MSC_VER */ + { PowerLinux::TGT_O_RDONLY, O_RDONLY }, + { PowerLinux::TGT_O_WRONLY, O_WRONLY }, + { PowerLinux::TGT_O_RDWR, O_RDWR }, + { PowerLinux::TGT_O_APPEND, O_APPEND }, + { PowerLinux::TGT_O_CREAT, O_CREAT }, + { PowerLinux::TGT_O_TRUNC, O_TRUNC }, + { PowerLinux::TGT_O_EXCL, O_EXCL }, + { PowerLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { PowerLinux::TGT_O_NOCTTY, O_NOCTTY }, +#ifdef O_SYNC + { PowerLinux::TGT_O_SYNC, O_SYNC }, +#endif +#ifdef O_LARGEFILE + { PowerLinux::TGT_O_LARGEFILE, O_LARGEFILE }, +#endif +#endif /* _MSC_VER */ +}; + +const int PowerLinux::NUM_OPEN_FLAGS = + (sizeof(PowerLinux::openFlagTable)/sizeof(PowerLinux::openFlagTable[0])); + diff --git a/src/arch/power/linux/linux.hh b/src/arch/power/linux/linux.hh new file mode 100644 index 000000000..c681c8baf --- /dev/null +++ b/src/arch/power/linux/linux.hh @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_LINUX_LINUX_HH__ +#define __ARCH_POWER_LINUX_LINUX_HH__ + +#include "kern/linux/linux.hh" + +/* + * This works for a 2.6.15 kernel. + */ + +class PowerLinux : public Linux +{ + public: + + typedef int32_t time_t; + + typedef struct { + uint64_t st_dev; + uint32_t __pad1; + uint32_t st_ino; + uint32_t st_mode; + uint32_t st_nlink; + uint32_t st_uid; + uint32_t st_gid; + uint64_t st_rdev; + uint32_t __pad2; + uint32_t st_size; + uint32_t st_blksize; + uint32_t st_blocks; + uint32_t st_atimeX; + uint32_t st_atime_nsec; + uint32_t st_mtimeX; + uint32_t st_mtime_nsec; + uint32_t st_ctimeX; + uint32_t st_ctime_nsec; + uint32_t __unused4; + uint32_t __unused5; + } tgt_stat; + + typedef struct { + uint64_t st_dev; + uint64_t st_ino; + uint32_t st_mode; + uint32_t st_nlink; + uint32_t st_uid; + uint32_t st_gid; + uint64_t st_rdev; + uint64_t __pad2; + uint64_t st_size; + uint32_t st_blksize; + uint32_t __blksize_pad; + uint64_t st_blocks; + uint32_t st_atimeX; + uint32_t st_atime_nsec; + uint32_t st_mtimeX; + uint32_t st_mtime_nsec; + uint32_t st_ctimeX; + uint32_t st_ctime_nsec; + uint32_t __unused4; + uint32_t __unused5; + } tgt_stat64; + + /// For times(). + struct tms { + int32_t tms_utime; //!< user time + int32_t tms_stime; //!< system time + int32_t tms_cutime; //!< user time of children + int32_t tms_cstime; //!< system time of children + }; + + /// This table maps the target open() flags to the corresponding + /// host open() flags. + static OpenFlagTransTable openFlagTable[]; + + /// Number of entries in openFlagTable[]. + static const int NUM_OPEN_FLAGS; + + //@{ + /// open(2) flag values. + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_CREAT = 00000100; //!< O_CREAT + static const int TGT_O_EXCL = 00000200; //!< O_EXCL + static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY + static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC + static const int TGT_O_APPEND = 00002000; //!< O_APPEND + static const int TGT_O_NONBLOCK = 00004000; //!< O_NONBLOCK + static const int TGT_O_SYNC = 00010000; //!< O_SYNC + static const int TGT_FASYNC = 00020000; //!< FASYNC + static const int TGT_O_DIRECTORY = 00040000; //!< O_DIRECTORY + static const int TGT_O_NOFOLLOW = 00100000; //!< O_NOFOLLOW + static const int TGT_O_LARGEFILE = 00200000; //!< O_LARGEFILE + static const int TGT_O_DIRECT = 00400000; //!< O_DIRECT + static const int TGT_O_NOATIME = 01000000; //!< O_NOATIME + //@} + + /// For mmap(). + static const unsigned TGT_MAP_ANONYMOUS = 0x800; + + //@{ + /// ioctl() command codes. + /// These are for the 2.6.15 kernel. Some have changed for + /// later versions. + static const unsigned TIOCGETP_ = 0x40067408; + static const unsigned TIOCSETP_ = 0x80067409; + static const unsigned TIOCSETN_ = 0x8006740a; + static const unsigned TIOCSETC_ = 0x80067411; + static const unsigned TIOCGETC_ = 0x40067412; + static const unsigned FIONREAD_ = 0x4004667f; + static const unsigned TIOCISATTY_ = 0x2000745e; + static const unsigned TIOCGETS_ = 0x402c7413; + static const unsigned TIOCGETA_ = 0x40147417; + static const unsigned TCSETAW_ = 0x80147419; + //@} +}; + +#endif // __ARCH_POWER_LINUX_LINUX_HH__ diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc new file mode 100644 index 000000000..504d0e334 --- /dev/null +++ b/src/arch/power/linux/process.cc @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Korey Sewell + * Stephen Hines + * Timothy M. Jones + */ + +#include "arch/power/linux/linux.hh" +#include "arch/power/linux/process.hh" +#include "arch/power/isa_traits.hh" + +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "kern/linux/linux.hh" + +#include "sim/process.hh" +#include "sim/syscall_emul.hh" +#include "sim/system.hh" + +using namespace std; +using namespace PowerISA; + +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + int index = 0; + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index)); + + strcpy(name->sysname, "Linux"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "2.6.16.19"); + strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); + strcpy(name->machine, "power"); + + name.copyOut(tc->getMemPort()); + return 0; +} + +SyscallDesc PowerLinuxProcess::syscallDescs[] = { + /* 0 */ SyscallDesc("syscall", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), + /* 2 */ SyscallDesc("fork", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), + /* 4 */ SyscallDesc("write", writeFunc), + /* 5 */ SyscallDesc("open", openFunc<PowerLinux>), + /* 6 */ SyscallDesc("close", closeFunc), + /* 7 */ SyscallDesc("waitpid", unimplementedFunc), //??? + /* 8 */ SyscallDesc("creat", unimplementedFunc), + /* 9 */ SyscallDesc("link", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), + /* 11 */ SyscallDesc("execve", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 13 */ SyscallDesc("time", timeFunc<PowerLinux>), + /* 14 */ SyscallDesc("mknod", unimplementedFunc), + /* 15 */ SyscallDesc("chmod", chmodFunc<PowerLinux>), + /* 16 */ SyscallDesc("lchown", chownFunc), + /* 17 */ SyscallDesc("break", brkFunc), //??? + /* 18 */ SyscallDesc("unused#18", unimplementedFunc), //??? + /* 19 */ SyscallDesc("lseek", lseekFunc), + /* 20 */ SyscallDesc("getpid", getpidFunc), + /* 21 */ SyscallDesc("mount", unimplementedFunc), + /* 22 */ SyscallDesc("umount", unimplementedFunc), + /* 23 */ SyscallDesc("setuid", setuidFunc), + /* 24 */ SyscallDesc("getuid", getuidFunc), + /* 25 */ SyscallDesc("stime", unimplementedFunc), + /* 26 */ SyscallDesc("ptrace", unimplementedFunc), + /* 27 */ SyscallDesc("alarm", unimplementedFunc), + /* 28 */ SyscallDesc("unused#28", unimplementedFunc), + /* 29 */ SyscallDesc("pause", unimplementedFunc), + /* 30 */ SyscallDesc("utime", unimplementedFunc), + /* 31 */ SyscallDesc("stty", unimplementedFunc), + /* 32 */ SyscallDesc("gtty", unimplementedFunc), + /* 33 */ SyscallDesc("access", unimplementedFunc), + /* 34 */ SyscallDesc("nice", unimplementedFunc), + /* 35 */ SyscallDesc("ftime", unimplementedFunc), + /* 36 */ SyscallDesc("sync", unimplementedFunc), + /* 37 */ SyscallDesc("kill", ignoreFunc), + /* 38 */ SyscallDesc("rename", renameFunc), + /* 39 */ SyscallDesc("mkdir", unimplementedFunc), + /* 40 */ SyscallDesc("rmdir", unimplementedFunc), + /* 41 */ SyscallDesc("dup", dupFunc), + /* 42 */ SyscallDesc("pipe", unimplementedFunc), + /* 43 */ SyscallDesc("times", timesFunc<PowerLinux>), + /* 44 */ SyscallDesc("prof", unimplementedFunc), + /* 45 */ SyscallDesc("brk", brkFunc), + /* 46 */ SyscallDesc("setgid", unimplementedFunc), + /* 47 */ SyscallDesc("getgid", getgidFunc), + /* 48 */ SyscallDesc("signal", ignoreFunc), + /* 49 */ SyscallDesc("geteuid", geteuidFunc), + /* 50 */ SyscallDesc("getegid", getegidFunc), + /* 51 */ SyscallDesc("acct", unimplementedFunc), + /* 52 */ SyscallDesc("umount2", unimplementedFunc), + /* 53 */ SyscallDesc("lock", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", ioctlFunc<PowerLinux>), + /* 55 */ SyscallDesc("fcntl", fcntlFunc), + /* 56 */ SyscallDesc("mpx", unimplementedFunc), + /* 57 */ SyscallDesc("setpgid", unimplementedFunc), + /* 58 */ SyscallDesc("ulimit", unimplementedFunc), + /* 59 */ SyscallDesc("unused#59", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), + /* 61 */ SyscallDesc("chroot", unimplementedFunc), + /* 62 */ SyscallDesc("ustat", unimplementedFunc), + /* 63 */ SyscallDesc("dup2", unimplementedFunc), + /* 64 */ SyscallDesc("getppid", getpagesizeFunc), + /* 65 */ SyscallDesc("getpgrp", unimplementedFunc), + /* 66 */ SyscallDesc("setsid", unimplementedFunc), + /* 67 */ SyscallDesc("sigaction",unimplementedFunc), + /* 68 */ SyscallDesc("sgetmask", unimplementedFunc), + /* 69 */ SyscallDesc("ssetmask", unimplementedFunc), + /* 70 */ SyscallDesc("setreuid", unimplementedFunc), + /* 71 */ SyscallDesc("setregid", unimplementedFunc), + /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc), + /* 73 */ SyscallDesc("sigpending", unimplementedFunc), + /* 74 */ SyscallDesc("sethostname", ignoreFunc), + /* 75 */ SyscallDesc("setrlimit", ignoreFunc), + /* 76 */ SyscallDesc("getrlimit", unimplementedFunc), + /* 77 */ SyscallDesc("getrusage", ignoreFunc), + /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc), + /* 79 */ SyscallDesc("settimeofday", unimplementedFunc), + /* 80 */ SyscallDesc("getgroups", unimplementedFunc), + /* 81 */ SyscallDesc("setgroups", unimplementedFunc), + /* 82 */ SyscallDesc("reserved#82", unimplementedFunc), + /* 83 */ SyscallDesc("symlink", unimplementedFunc), + /* 84 */ SyscallDesc("unused#84", unimplementedFunc), + /* 85 */ SyscallDesc("readlink", unimplementedFunc), + /* 86 */ SyscallDesc("uselib", unimplementedFunc), + /* 87 */ SyscallDesc("swapon", gethostnameFunc), + /* 88 */ SyscallDesc("reboot", unimplementedFunc), + /* 89 */ SyscallDesc("readdir", unimplementedFunc), + /* 90 */ SyscallDesc("mmap", mmapFunc<PowerLinux>), + /* 91 */ SyscallDesc("munmap",munmapFunc), + /* 92 */ SyscallDesc("truncate", truncateFunc), + /* 93 */ SyscallDesc("ftruncate", ftruncateFunc), + /* 94 */ SyscallDesc("fchmod", unimplementedFunc), + /* 95 */ SyscallDesc("fchown", unimplementedFunc), + /* 96 */ SyscallDesc("getpriority", unimplementedFunc), + /* 97 */ SyscallDesc("setpriority", unimplementedFunc), + /* 98 */ SyscallDesc("profil", unimplementedFunc), + /* 99 */ SyscallDesc("statfs", unimplementedFunc), + /* 100 */ SyscallDesc("fstatfs", unimplementedFunc), + /* 101 */ SyscallDesc("ioperm", unimplementedFunc), + /* 102 */ SyscallDesc("socketcall", unimplementedFunc), + /* 103 */ SyscallDesc("syslog", unimplementedFunc), + /* 104 */ SyscallDesc("setitimer", unimplementedFunc), + /* 105 */ SyscallDesc("getitimer", unimplementedFunc), + /* 106 */ SyscallDesc("stat", statFunc<PowerLinux>), + /* 107 */ SyscallDesc("lstat", unimplementedFunc), + /* 108 */ SyscallDesc("fstat", fstatFunc<PowerLinux>), + /* 109 */ SyscallDesc("unused#109", unimplementedFunc), + /* 110 */ SyscallDesc("iopl", unimplementedFunc), + /* 111 */ SyscallDesc("vhangup", unimplementedFunc), + /* 112 */ SyscallDesc("idle", ignoreFunc), + /* 113 */ SyscallDesc("vm86", unimplementedFunc), + /* 114 */ SyscallDesc("wait4", unimplementedFunc), + /* 115 */ SyscallDesc("swapoff", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 117 */ SyscallDesc("ipc", unimplementedFunc), + /* 118 */ SyscallDesc("fsync", unimplementedFunc), + /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), + /* 120 */ SyscallDesc("clone", unimplementedFunc), + /* 121 */ SyscallDesc("setdomainname", unimplementedFunc), + /* 122 */ SyscallDesc("uname", unameFunc), + /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc), + /* 124 */ SyscallDesc("adjtimex", unimplementedFunc), + /* 125 */ SyscallDesc("mprotect", ignoreFunc), + /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc), + /* 127 */ SyscallDesc("create_module", unimplementedFunc), + /* 128 */ SyscallDesc("init_module", unimplementedFunc), + /* 129 */ SyscallDesc("delete_module", unimplementedFunc), + /* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc), + /* 131 */ SyscallDesc("quotactl", unimplementedFunc), + /* 132 */ SyscallDesc("getpgid", unimplementedFunc), + /* 133 */ SyscallDesc("fchdir", unimplementedFunc), + /* 134 */ SyscallDesc("bdflush", unimplementedFunc), + /* 135 */ SyscallDesc("sysfs", unimplementedFunc), + /* 136 */ SyscallDesc("personality", unimplementedFunc), + /* 137 */ SyscallDesc("afs_syscall", unimplementedFunc), + /* 138 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 139 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 140 */ SyscallDesc("llseek", _llseekFunc), + /* 141 */ SyscallDesc("getdents", unimplementedFunc), + /* 142 */ SyscallDesc("newselect", unimplementedFunc), + /* 143 */ SyscallDesc("flock", unimplementedFunc), + /* 144 */ SyscallDesc("msync", unimplementedFunc), + /* 145 */ SyscallDesc("readv", unimplementedFunc), + /* 146 */ SyscallDesc("writev", writevFunc<PowerLinux>), + /* 147 */ SyscallDesc("getsid", unimplementedFunc), + /* 148 */ SyscallDesc("fdatasync", unimplementedFunc), + /* 149 */ SyscallDesc("sysctl", unimplementedFunc), + /* 150 */ SyscallDesc("mlock", unimplementedFunc), + /* 151 */ SyscallDesc("munlock", unimplementedFunc), + /* 152 */ SyscallDesc("mlockall", unimplementedFunc), + /* 153 */ SyscallDesc("munlockall", unimplementedFunc), + /* 154 */ SyscallDesc("sched_setparam", unimplementedFunc), + /* 155 */ SyscallDesc("sched_getparam", unimplementedFunc), + /* 156 */ SyscallDesc("sched_setscheduler", unimplementedFunc), + /* 157 */ SyscallDesc("sched_getscheduler", unimplementedFunc), + /* 158 */ SyscallDesc("sched_yield", unimplementedFunc), + /* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), + /* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), + /* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), + /* 162 */ SyscallDesc("nanosleep", unimplementedFunc), + /* 163 */ SyscallDesc("mremap", unimplementedFunc), + /* 164 */ SyscallDesc("setresuid", unimplementedFunc), + /* 165 */ SyscallDesc("getresuid", unimplementedFunc), + /* 166 */ SyscallDesc("vm862", unimplementedFunc), + /* 167 */ SyscallDesc("query_module", unimplementedFunc), + /* 168 */ SyscallDesc("poll", unimplementedFunc), + /* 169 */ SyscallDesc("nfsservctl", unimplementedFunc), + /* 170 */ SyscallDesc("setresgid", unimplementedFunc), + /* 171 */ SyscallDesc("getresgid", unimplementedFunc), + /* 172 */ SyscallDesc("prctl", unimplementedFunc), + /* 173 */ SyscallDesc("rt_sigaction", ignoreFunc), + /* 174 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), + /* 175 */ SyscallDesc("unknown#175", unimplementedFunc), + /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc), + /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), + /* 178 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc), + /* 179 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), + /* 180 */ SyscallDesc("pread64", unimplementedFunc), + /* 181 */ SyscallDesc("pwrite64", unimplementedFunc), + /* 182 */ SyscallDesc("chown", unimplementedFunc), + /* 183 */ SyscallDesc("getcwd", unimplementedFunc), + /* 184 */ SyscallDesc("capget", unimplementedFunc), + /* 185 */ SyscallDesc("capset", unimplementedFunc), + /* 186 */ SyscallDesc("sigaltstack", unimplementedFunc), + /* 187 */ SyscallDesc("sendfile", unimplementedFunc), + /* 188 */ SyscallDesc("getpmsg", unimplementedFunc), + /* 189 */ SyscallDesc("putpmsg", unimplementedFunc), + /* 190 */ SyscallDesc("ugetrlimit", ignoreFunc), + /* 191 */ SyscallDesc("getrlimit", unimplementedFunc), + /* 192 */ SyscallDesc("mmap2", mmapFunc<PowerLinux>), + /* 193 */ SyscallDesc("truncate64", unimplementedFunc), + /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func), + /* 195 */ SyscallDesc("stat64", stat64Func<PowerLinux>), + /* 196 */ SyscallDesc("lstat64", lstat64Func<PowerLinux>), + /* 197 */ SyscallDesc("fstat64", fstat64Func<PowerLinux>), + /* 198 */ SyscallDesc("lchown", unimplementedFunc), + /* 199 */ SyscallDesc("getuid", getuidFunc), + /* 200 */ SyscallDesc("getgid", getgidFunc), + /* 201 */ SyscallDesc("geteuid", geteuidFunc), + /* 202 */ SyscallDesc("getegid", getegidFunc), + /* 203 */ SyscallDesc("setreuid", unimplementedFunc), + /* 204 */ SyscallDesc("fcntl64", fcntl64Func), + /* 205 */ SyscallDesc("getgroups", unimplementedFunc), + /* 206 */ SyscallDesc("setgroups", unimplementedFunc), + /* 207 */ SyscallDesc("fchown", unimplementedFunc), + /* 208 */ SyscallDesc("setresuid", unimplementedFunc), + /* 209 */ SyscallDesc("getresuid", unimplementedFunc), + /* 210 */ SyscallDesc("setresgid", unimplementedFunc), + /* 211 */ SyscallDesc("getresgid", unimplementedFunc), + /* 212 */ SyscallDesc("chown", unimplementedFunc), + /* 213 */ SyscallDesc("setuid", unimplementedFunc), + /* 214 */ SyscallDesc("setgid", unimplementedFunc), + /* 215 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 216 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 217 */ SyscallDesc("getdents64", unimplementedFunc), + /* 218 */ SyscallDesc("pivot_root", unimplementedFunc), + /* 219 */ SyscallDesc("mincore", unimplementedFunc), + /* 220 */ SyscallDesc("madvise", unimplementedFunc), + /* 221 */ SyscallDesc("unknown#221", unimplementedFunc), + /* 222 */ SyscallDesc("tux", unimplementedFunc), + /* 223 */ SyscallDesc("unknown#223", unimplementedFunc), + /* 224 */ SyscallDesc("gettid", unimplementedFunc), + /* 225 */ SyscallDesc("readahead", unimplementedFunc), + /* 226 */ SyscallDesc("setxattr", unimplementedFunc), + /* 227 */ SyscallDesc("lsetxattr", unimplementedFunc), + /* 228 */ SyscallDesc("fsetxattr", unimplementedFunc), + /* 229 */ SyscallDesc("getxattr", unimplementedFunc), + /* 230 */ SyscallDesc("lgetxattr", unimplementedFunc), + /* 231 */ SyscallDesc("fgetxattr", unimplementedFunc), + /* 232 */ SyscallDesc("listxattr", unimplementedFunc), + /* 233 */ SyscallDesc("llistxattr", unimplementedFunc), + /* 234 */ SyscallDesc("exit_group", exitGroupFunc), + /* 235 */ SyscallDesc("removexattr", unimplementedFunc), + /* 236 */ SyscallDesc("lremovexattr", unimplementedFunc), + /* 237 */ SyscallDesc("fremovexattr", unimplementedFunc), + /* 238 */ SyscallDesc("tkill", unimplementedFunc), + /* 239 */ SyscallDesc("sendfile64", unimplementedFunc), + /* 240 */ SyscallDesc("futex", unimplementedFunc), + /* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc), + /* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc), + /* 243 */ SyscallDesc("io_setup", unimplementedFunc), + /* 244 */ SyscallDesc("io_destory", unimplementedFunc), + /* 245 */ SyscallDesc("io_getevents", unimplementedFunc), + /* 246 */ SyscallDesc("io_submit", unimplementedFunc), + /* 247 */ SyscallDesc("io_cancel", unimplementedFunc), + /* 248 */ SyscallDesc("unknown#248", unimplementedFunc), + /* 249 */ SyscallDesc("lookup_dcookie", unimplementedFunc), + /* 250 */ SyscallDesc("epoll_create", unimplementedFunc), + /* 251 */ SyscallDesc("epoll_ctl", unimplementedFunc), + /* 252 */ SyscallDesc("epoll_wait", unimplementedFunc), + /* 253 */ SyscallDesc("remap_file_pages", unimplementedFunc), + /* 254 */ SyscallDesc("set_thread_area", unimplementedFunc), + /* 255 */ SyscallDesc("get_thread_area", unimplementedFunc), + /* 256 */ SyscallDesc("set_tid_address", unimplementedFunc), + /* 257 */ SyscallDesc("timer_create", unimplementedFunc), + /* 258 */ SyscallDesc("timer_settime", unimplementedFunc), + /* 259 */ SyscallDesc("timer_gettime", unimplementedFunc), + /* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc), + /* 261 */ SyscallDesc("timer_delete", unimplementedFunc), + /* 262 */ SyscallDesc("clock_settime", unimplementedFunc), + /* 263 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 264 */ SyscallDesc("clock_getres", unimplementedFunc), + /* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc), + /* 266 */ SyscallDesc("statfs64", unimplementedFunc), + /* 267 */ SyscallDesc("fstatfs64", unimplementedFunc), + /* 268 */ SyscallDesc("tgkill", unimplementedFunc), + /* 269 */ SyscallDesc("utimes", unimplementedFunc), + /* 270 */ SyscallDesc("arm_fadvise64_64", unimplementedFunc), + /* 271 */ SyscallDesc("pciconfig_iobase", unimplementedFunc), + /* 272 */ SyscallDesc("pciconfig_read", unimplementedFunc), + /* 273 */ SyscallDesc("pciconfig_write", unimplementedFunc), + /* 274 */ SyscallDesc("mq_open", unimplementedFunc), + /* 275 */ SyscallDesc("mq_unlink", unimplementedFunc), + /* 276 */ SyscallDesc("mq_timedsend", unimplementedFunc), + /* 277 */ SyscallDesc("mq_timedreceive", unimplementedFunc), + /* 278 */ SyscallDesc("mq_notify", unimplementedFunc), + /* 279 */ SyscallDesc("mq_getsetattr", unimplementedFunc), + /* 280 */ SyscallDesc("waitid", unimplementedFunc), + /* 281 */ SyscallDesc("socket", unimplementedFunc), + /* 282 */ SyscallDesc("bind", unimplementedFunc), + /* 283 */ SyscallDesc("connect", unimplementedFunc), + /* 284 */ SyscallDesc("listen", unimplementedFunc), + /* 285 */ SyscallDesc("accept", unimplementedFunc), + /* 286 */ SyscallDesc("getsockname", unimplementedFunc), + /* 287 */ SyscallDesc("getpeername", unimplementedFunc), + /* 288 */ SyscallDesc("socketpair", unimplementedFunc), + /* 289 */ SyscallDesc("send", unimplementedFunc), + /* 290 */ SyscallDesc("sendto", unimplementedFunc), + /* 291 */ SyscallDesc("recv", unimplementedFunc), + /* 292 */ SyscallDesc("recvfrom", unimplementedFunc), + /* 293 */ SyscallDesc("shutdown", unimplementedFunc), + /* 294 */ SyscallDesc("setsockopt", unimplementedFunc), + /* 295 */ SyscallDesc("getsockopt", unimplementedFunc), + /* 296 */ SyscallDesc("sendmsg", unimplementedFunc), + /* 297 */ SyscallDesc("rcvmsg", unimplementedFunc), + /* 298 */ SyscallDesc("semop", unimplementedFunc), + /* 299 */ SyscallDesc("semget", unimplementedFunc), + /* 300 */ SyscallDesc("semctl", unimplementedFunc), + /* 301 */ SyscallDesc("msgsend", unimplementedFunc), + /* 302 */ SyscallDesc("msgrcv", unimplementedFunc), + /* 303 */ SyscallDesc("msgget", unimplementedFunc), + /* 304 */ SyscallDesc("msgctl", unimplementedFunc), + /* 305 */ SyscallDesc("shmat", unimplementedFunc), + /* 306 */ SyscallDesc("shmdt", unimplementedFunc), + /* 307 */ SyscallDesc("shmget", unimplementedFunc), + /* 308 */ SyscallDesc("shmctl", unimplementedFunc), + /* 309 */ SyscallDesc("add_key", unimplementedFunc), + /* 310 */ SyscallDesc("request_key", unimplementedFunc), + /* 311 */ SyscallDesc("keyctl", unimplementedFunc), + /* 312 */ SyscallDesc("semtimedop", unimplementedFunc), + /* 313 */ SyscallDesc("vserver", unimplementedFunc), + /* 314 */ SyscallDesc("ioprio_set", unimplementedFunc), + /* 315 */ SyscallDesc("ioprio_get", unimplementedFunc), + /* 316 */ SyscallDesc("inotify_init", unimplementedFunc), + /* 317 */ SyscallDesc("inotify_add_watch", unimplementedFunc), + /* 318 */ SyscallDesc("inotify_rm_watch", unimplementedFunc), + /* 319 */ SyscallDesc("mbind", unimplementedFunc), + /* 320 */ SyscallDesc("get_mempolicy", unimplementedFunc), + /* 321 */ SyscallDesc("set_mempolicy", unimplementedFunc), + /* 322 */ SyscallDesc("openat", unimplementedFunc), + /* 323 */ SyscallDesc("mkdirat", unimplementedFunc), + /* 324 */ SyscallDesc("mknodat", unimplementedFunc), + /* 325 */ SyscallDesc("fchownat", unimplementedFunc), + /* 326 */ SyscallDesc("futimesat", unimplementedFunc), + /* 327 */ SyscallDesc("fstatat64", unimplementedFunc), + /* 328 */ SyscallDesc("unlinkat", unimplementedFunc), + /* 329 */ SyscallDesc("renameat", unimplementedFunc), + /* 330 */ SyscallDesc("linkat", unimplementedFunc), + /* 331 */ SyscallDesc("symlinkat", unimplementedFunc), + /* 332 */ SyscallDesc("readlinkat", unimplementedFunc), + /* 333 */ SyscallDesc("fchmodat", unimplementedFunc), + /* 334 */ SyscallDesc("faccessat", unimplementedFunc), + /* 335 */ SyscallDesc("pselect6", unimplementedFunc), + /* 336 */ SyscallDesc("ppoll", unimplementedFunc), + /* 337 */ SyscallDesc("unshare", unimplementedFunc), + /* 338 */ SyscallDesc("set_robust_list", unimplementedFunc), + /* 339 */ SyscallDesc("get_robust_list", unimplementedFunc), + /* 340 */ SyscallDesc("splice", unimplementedFunc), + /* 341 */ SyscallDesc("arm_sync_file_range", unimplementedFunc), + /* 342 */ SyscallDesc("tee", unimplementedFunc), + /* 343 */ SyscallDesc("vmsplice", unimplementedFunc), + /* 344 */ SyscallDesc("move_pages", unimplementedFunc), + /* 345 */ SyscallDesc("getcpu", unimplementedFunc), + /* 346 */ SyscallDesc("epoll_pwait", unimplementedFunc), +}; + +PowerLinuxProcess::PowerLinuxProcess(LiveProcessParams * params, + ObjectFile *objFile) + : PowerLiveProcess(params, objFile), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) +{ +} + +SyscallDesc* +PowerLinuxProcess::getDesc(int callnum) +{ + if (callnum < 0 || callnum > Num_Syscall_Descs) + return NULL; + + return &syscallDescs[callnum]; +} + +void +PowerLinuxProcess::startup() +{ + PowerLiveProcess::startup(); +} + +PowerISA::IntReg +PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int &i) +{ + // Linux apparently allows more parameter than the ABI says it should. + // This limit may need to be increased even further. + assert(i < 6); + return tc->readIntReg(ArgumentReg0 + i++); +} + +void +PowerLinuxProcess::setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val) +{ + // Linux apparently allows more parameter than the ABI says it should. + // This limit may need to be increased even further. + assert(i < 6); + tc->setIntReg(ArgumentReg0 + i, val); +} diff --git a/src/mem/slicc/generator/fileio.cc b/src/arch/power/linux/process.hh index 15eccd3ca..db6759a77 100644 --- a/src/mem/slicc/generator/fileio.cc +++ b/src/arch/power/linux/process.hh @@ -1,6 +1,6 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,42 +25,34 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + * Timothy M. Jones */ -/* - * fileio.C - * - * Description: See fileio.hh - * - * $Id: fileio.C,v 3.3 2003/07/10 18:08:08 milo Exp $ - * - * */ +#ifndef __POWER_LINUX_PROCESS_HH__ +#define __POWER_LINUX_PROCESS_HH__ + +#include "arch/power/process.hh" -#include "mem/slicc/generator/fileio.hh" -void conditionally_write_file(string filename, ostringstream& sstr) +/// A process with emulated PPC/Linux syscalls. +class PowerLinuxProcess : public PowerLiveProcess { - ofstream out; - ifstream in; - string input_file; + public: + PowerLinuxProcess(LiveProcessParams * params, ObjectFile *objFile); + + virtual SyscallDesc* getDesc(int callnum); + + void startup(); + + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i); + void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); - // Read in the file if it exists - in.open(filename.c_str()); - char c; - while (in.get(c)) { - input_file += c; - } - in.close(); + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; - // Check to see if the file is the same as what we want to write - if (input_file != sstr.str()) { - cout << " Overwriting file: " << filename << endl; - // Overwrite the old file with the new file - out.open(filename.c_str()); - out << sstr.str(); - out.close(); - } else { - //cout << " Keeping old file: " << filename << endl; - } -} + const int Num_Syscall_Descs; +}; +#endif // __POWER_LINUX_PROCESS_HH__ diff --git a/src/mem/slicc/ast/PairAST.cc b/src/arch/power/locked_mem.hh index c42843cce..56ab1d4a0 100644 --- a/src/mem/slicc/ast/PairAST.cc +++ b/src/arch/power/locked_mem.hh @@ -1,6 +1,7 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,48 +26,39 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt + * Stephen Hines + * Timothy M. Jones */ -/* - * PairAST.C - * - * Description: See PairAST.hh - * - * $Id$ +#ifndef __ARCH_POWER_LOCKED_MEM_HH__ +#define __ARCH_POWER_LOCKED_MEM_HH__ + +/** + * @file * + * ISA-specific helper functions for locked memory accesses. */ -#include "mem/slicc/ast/PairAST.hh" +#include "mem/request.hh" -PairAST::PairAST(string* key_ptr, string* value_ptr) - : AST() +namespace PowerISA { - m_key_ptr = key_ptr; - m_value_ptr = value_ptr; -} - -PairAST::PairAST(string key, string* value_ptr) - : AST() -{ - m_key_ptr = new string(key); - m_value_ptr = value_ptr; -} -PairAST::PairAST(string key, string value) - : AST() +template <class XC> +inline void +handleLockedRead(XC *xc, Request *req) { - m_key_ptr = new string(key); - m_value_ptr = new string(value); } -PairAST::~PairAST() +template <class XC> +inline bool +handleLockedWrite(XC *xc, Request *req) { - delete m_key_ptr; - delete m_value_ptr; + return true; } -void PairAST::print(ostream& out) const -{ - out << "[" << *m_key_ptr << "=" << *m_value_ptr << "]" << endl; -} +} // PowerISA namespace +#endif // __ARCH_POWER_LOCKED_MEM_HH__ diff --git a/src/mem/slicc/ast/PairListAST.cc b/src/arch/power/microcode_rom.hh index 76892d437..e35db5112 100644 --- a/src/mem/slicc/ast/PairListAST.cc +++ b/src/arch/power/microcode_rom.hh @@ -1,6 +1,6 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,25 +25,21 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PairListAST.C - * - * Description: See PairListAST.hh - * - * $Id$ * + * Authors: Gabe Black + * Timothy M. Jones */ -#include "mem/slicc/ast/PairListAST.hh" +#ifndef __ARCH_POWER_MICROCODE_ROM_HH__ +#define __ARCH_POWER_MICROCODE_ROM_HH__ -void PairListAST::addPair(PairAST* pair_ptr) -{ - getPairs().add(pair_ptr->key(), pair_ptr->value()); -} +#include "sim/microcode_rom.hh" -void PairListAST::print(ostream& out) const +namespace PowerISA { - out << "[PairListAST] " << getPairs(); -} + +using ::MicrocodeRom; + +} // PowerISA namespace + +#endif // __ARCH_POWER_MICROCODE_ROM_HH__ diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.hh b/src/arch/power/miscregs.hh index 1df853514..cd9815b2a 100644 --- a/src/mem/slicc/ast/CheckAllocateStatementAST.hh +++ b/src/arch/power/miscregs.hh @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,58 +24,72 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ * + * Authors: Timothy M. Jones */ -#ifndef CHECKALLOCATESTATEMENTAST_H -#define CHECKALLOCATESTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class VarExprAST; -class Var; +#ifndef __ARCH_POWER_MISCREGS_HH__ +#define __ARCH_POWER_MISCREGS_HH__ -class CheckAllocateStatementAST : public StatementAST { -public: - // Constructors - CheckAllocateStatementAST(VarExprAST* variable); +#include "base/bitunion.hh" - // Destructor - ~CheckAllocateStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods +namespace PowerISA +{ - // Private copy constructor and assignment operator - CheckAllocateStatementAST(const CheckAllocateStatementAST& obj); - CheckAllocateStatementAST& operator=(const CheckAllocateStatementAST& obj); +enum MiscRegIndex { + NUM_MISCREGS = 0 +}; - // Data Members (m_ prefix) - VarExprAST* m_variable; +const char * const miscRegName[NUM_MISCREGS] = { }; -// Output operator declaration -ostream& operator<<(ostream& out, const CheckAllocateStatementAST& obj); +BitUnion32(Cr) + Bitfield<31,28> cr0; + Bitfield<27,24> cr1; +EndBitUnion(Cr) -// ******************* Definitions ******************* +BitUnion32(Xer) + Bitfield<31> so; + Bitfield<30> ov; + Bitfield<29> ca; +EndBitUnion(Xer) -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const CheckAllocateStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} +BitUnion32(Fpscr) + Bitfield<31> fx; + Bitfield<30> fex; + Bitfield<29> vx; + Bitfield<28> ox; + Bitfield<27> ux; + Bitfield<26> zx; + Bitfield<25> xx; + Bitfield<24> vxsnan; + Bitfield<23> vxisi; + Bitfield<22> vxidi; + Bitfield<21> vxzdz; + Bitfield<20> vximz; + Bitfield<19> vxvc; + Bitfield<18> fr; + Bitfield<17> fi; + SubBitUnion(fprf, 16, 12) + Bitfield<16> c; + SubBitUnion(fpcc, 15, 12) + Bitfield<15> fl; + Bitfield<14> fg; + Bitfield<13> fe; + Bitfield<12> fu; + EndSubBitUnion(fpcc) + EndSubBitUnion(fprf) + Bitfield<10> vxsqrt; + Bitfield<9> vxcvi; + Bitfield<8> ve; + Bitfield<7> oe; + Bitfield<6> ue; + Bitfield<5> ze; + Bitfield<4> xe; + Bitfield<3> ni; + Bitfield<2,1> rn; +EndBitUnion(Fpscr) + +}; // PowerISA namespace -#endif //CHECKALLOCATESTATEMENTAST_H +#endif // __ARCH_POWER_MISCREGS_HH__ diff --git a/src/arch/power/mmaped_ipr.hh b/src/arch/power/mmaped_ipr.hh new file mode 100644 index 000000000..bd1ea10b3 --- /dev/null +++ b/src/arch/power/mmaped_ipr.hh @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_MMAPED_IPR_HH__ +#define __ARCH_POWER_MMAPED_IPR_HH__ + +/** + * @file + * + * ISA-specific helper functions for memory mapped IPR accesses. + */ + +#include "base/misc.hh" +#include "mem/packet.hh" + +class ThreadContext; + +namespace PowerISA +{ + +inline Tick +handleIprRead(ThreadContext *xc, Packet *pkt) +{ + panic("No implementation for handleIprRead in POWER\n"); +} + +inline Tick +handleIprWrite(ThreadContext *xc, Packet *pkt) +{ + panic("No implementation for handleIprWrite in POWER\n"); +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_MMAPED_IPR_HH__ diff --git a/src/mem/slicc/ast/EnumExprAST.cc b/src/arch/power/pagetable.cc index 0d8af0e9f..862404578 100644 --- a/src/mem/slicc/ast/EnumExprAST.cc +++ b/src/arch/power/pagetable.cc @@ -1,6 +1,8 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,52 +27,56 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnumExprAST.C - * - * Description: See EnumExprAST.hh - * - * $Id: EnumExprAST.C,v 3.1 2003/07/10 18:08:06 milo Exp $ * + * Authors: Nathan Binkert + * Steve Reinhardt + * Jaidev Patwardhan + * Stephen Hines + * Timothy M. Jones */ -#include "mem/slicc/ast/EnumExprAST.hh" +#include "arch/power/pagetable.hh" +#include "sim/serialize.hh" -EnumExprAST::EnumExprAST(TypeAST* type_ast_ptr, - string* value_ptr) - : ExprAST() +namespace PowerISA { - assert(value_ptr != NULL); - assert(type_ast_ptr != NULL); - m_type_ast_ptr = type_ast_ptr; - m_value_ptr = value_ptr; -} -EnumExprAST::~EnumExprAST() +void +PTE::serialize(std::ostream &os) { - delete m_type_ast_ptr; - delete m_value_ptr; + SERIALIZE_SCALAR(Mask); + SERIALIZE_SCALAR(VPN); + SERIALIZE_SCALAR(asid); + SERIALIZE_SCALAR(G); + SERIALIZE_SCALAR(PFN0); + SERIALIZE_SCALAR(D0); + SERIALIZE_SCALAR(V0); + SERIALIZE_SCALAR(C0); + SERIALIZE_SCALAR(PFN1); + SERIALIZE_SCALAR(D1); + SERIALIZE_SCALAR(V1); + SERIALIZE_SCALAR(C1); + SERIALIZE_SCALAR(AddrShiftAmount); + SERIALIZE_SCALAR(OffsetMask); } -Type* EnumExprAST::generate(string& code) const +void +PTE::unserialize(Checkpoint *cp, const std::string §ion) { - Type* type_ptr = m_type_ast_ptr->lookupType(); - code += type_ptr->cIdent() + "_" + (*m_value_ptr); - - // Make sure the enumeration value exists - if (!type_ptr->enumExist(*m_value_ptr)) { - error("Type '" + m_type_ast_ptr->toString() + "' does not have enumeration '" + *m_value_ptr + "'"); - } - - // Return the proper type - return type_ptr; + UNSERIALIZE_SCALAR(Mask); + UNSERIALIZE_SCALAR(VPN); + UNSERIALIZE_SCALAR(asid); + UNSERIALIZE_SCALAR(G); + UNSERIALIZE_SCALAR(PFN0); + UNSERIALIZE_SCALAR(D0); + UNSERIALIZE_SCALAR(V0); + UNSERIALIZE_SCALAR(C0); + UNSERIALIZE_SCALAR(PFN1); + UNSERIALIZE_SCALAR(D1); + UNSERIALIZE_SCALAR(V1); + UNSERIALIZE_SCALAR(C1); + UNSERIALIZE_SCALAR(AddrShiftAmount); + UNSERIALIZE_SCALAR(OffsetMask); } -void EnumExprAST::print(ostream& out) const -{ - string str; - str += m_type_ast_ptr->toString()+":"+(*m_value_ptr); - out << "[EnumExpr: " << str << "]"; -} +} // PowerISA namespace diff --git a/src/arch/power/pagetable.hh b/src/arch/power/pagetable.hh new file mode 100644 index 000000000..bd2b9d397 --- /dev/null +++ b/src/arch/power/pagetable.hh @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Jaidev Patwardhan + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_PAGETABLE_H__ +#define __ARCH_POWER_PAGETABLE_H__ + +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" +#include "arch/power/vtophys.hh" +#include "config/full_system.hh" + +namespace PowerISA { + +struct VAddr +{ + static const int ImplBits = 43; + static const Addr ImplMask = (ULL(1) << ImplBits) - 1; + static const Addr UnImplMask = ~ImplMask; + + Addr addr; + + VAddr(Addr a) + : addr(a) + {} + + operator Addr() const + { + return addr; + } + + const VAddr + &operator=(Addr a) + { + addr = a; + return *this; + } + + Addr + vpn() const + { + return (addr & ImplMask) >> PageShift; + } + + Addr + page() const + { + return addr & Page_Mask; + } + + Addr + offset() const + { + return addr & PageOffset; + } + + Addr + level3() const + { + return PowerISA::PteAddr(addr >> PageShift); + } + + Addr + level2() const + { + return PowerISA::PteAddr(addr >> (NPtePageShift + PageShift)); + } + + Addr + level1() const + { + return PowerISA::PteAddr(addr >> (2 * NPtePageShift + PageShift)); + } +}; + +// ITB/DTB page table entry +struct PTE +{ + // What parts of the VAddr (from bits 28..11) should be used in + // translation (includes Mask and MaskX from PageMask) + Addr Mask; + + // Virtual Page Number (/2) (Includes VPN2 + VPN2X .. bits 31..11 + // from EntryHi) + Addr VPN; + + // Address Space ID (8 bits) // Lower 8 bits of EntryHi + uint8_t asid; + + // Global Bit - Obtained by an *AND* of EntryLo0 and EntryLo1 G bit + bool G; + + /* Contents of Entry Lo0 */ + Addr PFN0; // Physical Frame Number - Even + bool D0; // Even entry Dirty Bit + bool V0; // Even entry Valid Bit + uint8_t C0; // Cache Coherency Bits - Even + + /* Contents of Entry Lo1 */ + Addr PFN1; // Physical Frame Number - Odd + bool D1; // Odd entry Dirty Bit + bool V1; // Odd entry Valid Bit + uint8_t C1; // Cache Coherency Bits (3 bits) + + // The next few variables are put in as optimizations to reduce TLB + // lookup overheads. For a given Mask, what is the address shift amount + // and what is the OffsetMask + int AddrShiftAmount; + int OffsetMask; + + bool + Valid() + { + return (V0 | V1); + }; + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_PAGETABLE_H__ + diff --git a/src/arch/power/predecoder.hh b/src/arch/power/predecoder.hh new file mode 100644 index 000000000..1f3ac41cb --- /dev/null +++ b/src/arch/power/predecoder.hh @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_ARM_PREDECODER_HH__ +#define __ARCH_ARM_PREDECODER_HH__ + +#include "arch/power/types.hh" +#include "base/misc.hh" +#include "base/types.hh" + +class ThreadContext; + +namespace PowerISA +{ + +class Predecoder +{ + protected: + ThreadContext * tc; + + // The extended machine instruction being generated + ExtMachInst emi; + + public: + Predecoder(ThreadContext * _tc) + : tc(_tc) + { + } + + ThreadContext * + getTC() + { + return tc; + } + + void + setTC(ThreadContext * _tc) + { + tc = _tc; + } + + void + process() + { + } + + void + reset() + { + } + + // Use this to give data to the predecoder. This should be used + // when there is control flow. + void + moreBytes(Addr pc, Addr fetchPC, MachInst inst) + { + emi = inst; + } + + // Use this to give data to the predecoder. This should be used + // when instructions are executed in order. + void + moreBytes(MachInst machInst) + { + moreBytes(0, 0, machInst); + } + + bool + needMoreBytes() + { + return true; + } + + bool + extMachInstReady() + { + return true; + } + + // This returns a constant reference to the ExtMachInst to avoid a copy + const ExtMachInst & + getExtMachInst() + { + return emi; + } +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_PREDECODER_HH__ diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc new file mode 100644 index 000000000..92f993e4c --- /dev/null +++ b/src/arch/power/process.cc @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + * Timothy M. Jones + */ + +#include "arch/power/isa_traits.hh" +#include "arch/power/process.hh" +#include "arch/power/types.hh" +#include "base/loader/elf_object.hh" +#include "base/loader/object_file.hh" +#include "base/misc.hh" +#include "cpu/thread_context.hh" +#include "mem/page_table.hh" +#include "mem/translating_port.hh" +#include "sim/process_impl.hh" +#include "sim/system.hh" + +using namespace std; +using namespace PowerISA; + +PowerLiveProcess::PowerLiveProcess(LiveProcessParams *params, + ObjectFile *objFile) + : LiveProcess(params, objFile) +{ + stack_base = 0xbf000000L; + + // Set pointer for next thread stack. Reserve 8M for main stack. + next_thread_stack_base = stack_base - (8 * 1024 * 1024); + + // Set up break point (Top of Heap) + brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); + brk_point = roundUp(brk_point, VMPageSize); + + // Set up region for mmaps. For now, start at bottom of kuseg space. + mmap_start = mmap_end = 0x70000000L; +} + +void +PowerLiveProcess::startup() +{ + argsInit(MachineBytes, VMPageSize); +} + +void +PowerLiveProcess::argsInit(int intSize, int pageSize) +{ + typedef AuxVector<uint32_t> auxv_t; + std::vector<auxv_t> auxv; + + string filename; + if (argv.size() < 1) + filename = ""; + else + filename = argv[0]; + + //We want 16 byte alignment + uint64_t align = 16; + + // Overloaded argsInit so that we can fine-tune for POWER architecture + Process::startup(); + + // load object file into target memory + objFile->loadSections(initVirtMem); + + //Setup the auxilliary vectors. These will already have endian conversion. + //Auxilliary vectors are loaded only for elf formatted executables. + ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile); + if (elfObject) { + uint32_t features = 0; + + //Bits which describe the system hardware capabilities + //XXX Figure out what these should be + auxv.push_back(auxv_t(M5_AT_HWCAP, features)); + //The system page size + auxv.push_back(auxv_t(M5_AT_PAGESZ, PowerISA::VMPageSize)); + //Frequency at which times() increments + auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64)); + // For statically linked executables, this is the virtual address of the + // program header tables if they appear in the executable image + auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable())); + // This is the size of a program header entry from the elf file. + auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize())); + // This is the number of program headers from the original elf file. + auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount())); + //This is the address of the elf "interpreter", It should be set + //to 0 for regular executables. It should be something else + //(not sure what) for dynamic libraries. + auxv.push_back(auxv_t(M5_AT_BASE, 0)); + + //XXX Figure out what this should be. + auxv.push_back(auxv_t(M5_AT_FLAGS, 0)); + //The entry point to the program + auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint())); + //Different user and group IDs + auxv.push_back(auxv_t(M5_AT_UID, uid())); + auxv.push_back(auxv_t(M5_AT_EUID, euid())); + auxv.push_back(auxv_t(M5_AT_GID, gid())); + auxv.push_back(auxv_t(M5_AT_EGID, egid())); + //Whether to enable "secure mode" in the executable + auxv.push_back(auxv_t(M5_AT_SECURE, 0)); + //The filename of the program + auxv.push_back(auxv_t(M5_AT_EXECFN, 0)); + //The string "v51" with unknown meaning + auxv.push_back(auxv_t(M5_AT_PLATFORM, 0)); + } + + //Figure out how big the initial stack nedes to be + + // A sentry NULL void pointer at the top of the stack. + int sentry_size = intSize; + + string platform = "v51"; + int platform_size = platform.size() + 1; + + // The aux vectors are put on the stack in two groups. The first group are + // the vectors that are generated as the elf is loaded. The second group + // are the ones that were computed ahead of time and include the platform + // string. + int aux_data_size = filename.size() + 1; + + int env_data_size = 0; + for (int i = 0; i < envp.size(); ++i) { + env_data_size += envp[i].size() + 1; + } + int arg_data_size = 0; + for (int i = 0; i < argv.size(); ++i) { + arg_data_size += argv[i].size() + 1; + } + + int info_block_size = + sentry_size + env_data_size + arg_data_size + + aux_data_size + platform_size; + + //Each auxilliary vector is two 4 byte words + int aux_array_size = intSize * 2 * (auxv.size() + 1); + + int envp_array_size = intSize * (envp.size() + 1); + int argv_array_size = intSize * (argv.size() + 1); + + int argc_size = intSize; + + //Figure out the size of the contents of the actual initial frame + int frame_size = + info_block_size + + aux_array_size + + envp_array_size + + argv_array_size + + argc_size; + + //There needs to be padding after the auxiliary vector data so that the + //very bottom of the stack is aligned properly. + int partial_size = frame_size; + int aligned_partial_size = roundUp(partial_size, align); + int aux_padding = aligned_partial_size - partial_size; + + int space_needed = frame_size + aux_padding; + + stack_min = stack_base - space_needed; + stack_min = roundDown(stack_min, align); + stack_size = stack_base - stack_min; + + // map memory + pTable->allocate(roundDown(stack_min, pageSize), + roundUp(stack_size, pageSize)); + + // map out initial stack contents + uint32_t sentry_base = stack_base - sentry_size; + uint32_t aux_data_base = sentry_base - aux_data_size; + uint32_t env_data_base = aux_data_base - env_data_size; + uint32_t arg_data_base = env_data_base - arg_data_size; + uint32_t platform_base = arg_data_base - platform_size; + uint32_t auxv_array_base = platform_base - aux_array_size - aux_padding; + uint32_t envp_array_base = auxv_array_base - envp_array_size; + uint32_t argv_array_base = envp_array_base - argv_array_size; + uint32_t argc_base = argv_array_base - argc_size; + + DPRINTF(Stack, "The addresses of items on the initial stack:\n"); + DPRINTF(Stack, "0x%x - aux data\n", aux_data_base); + DPRINTF(Stack, "0x%x - env data\n", env_data_base); + DPRINTF(Stack, "0x%x - arg data\n", arg_data_base); + DPRINTF(Stack, "0x%x - platform base\n", platform_base); + DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base); + DPRINTF(Stack, "0x%x - envp array\n", envp_array_base); + DPRINTF(Stack, "0x%x - argv array\n", argv_array_base); + DPRINTF(Stack, "0x%x - argc \n", argc_base); + DPRINTF(Stack, "0x%x - stack min\n", stack_min); + + // write contents to stack + + // figure out argc + uint32_t argc = argv.size(); + uint32_t guestArgc = PowerISA::htog(argc); + + //Write out the sentry void * + uint32_t sentry_NULL = 0; + initVirtMem->writeBlob(sentry_base, + (uint8_t*)&sentry_NULL, sentry_size); + + //Fix up the aux vectors which point to other data + for (int i = auxv.size() - 1; i >= 0; i--) { + if (auxv[i].a_type == M5_AT_PLATFORM) { + auxv[i].a_val = platform_base; + initVirtMem->writeString(platform_base, platform.c_str()); + } else if (auxv[i].a_type == M5_AT_EXECFN) { + auxv[i].a_val = aux_data_base; + initVirtMem->writeString(aux_data_base, filename.c_str()); + } + } + + //Copy the aux stuff + for (int x = 0; x < auxv.size(); x++) + { + initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize, + (uint8_t*)&(auxv[x].a_type), intSize); + initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize, + (uint8_t*)&(auxv[x].a_val), intSize); + } + //Write out the terminating zeroed auxilliary vector + const uint64_t zero = 0; + initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(), + (uint8_t*)&zero, 2 * intSize); + + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); + copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); + + initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); + + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + //Set the stack pointer register + tc->setIntReg(StackPointerReg, stack_min); + + Addr prog_entry = objFile->entryPoint(); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + + //Align the "stack_min" to a page boundary. + stack_min = roundDown(stack_min, pageSize); +} + +PowerISA::IntReg +PowerLiveProcess::getSyscallArg(ThreadContext *tc, int &i) +{ + assert(i < 5); + return tc->readIntReg(ArgumentReg0 + i++); +} + +void +PowerLiveProcess::setSyscallArg(ThreadContext *tc, + int i, PowerISA::IntReg val) +{ + assert(i < 5); + tc->setIntReg(ArgumentReg0 + i, val); +} + +void +PowerLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + tc->setIntReg(ReturnValueReg, return_value.value()); +} diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh new file mode 100644 index 000000000..ede75f05f --- /dev/null +++ b/src/arch/power/process.hh @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + * Timothy M. Jones + */ + +#ifndef __POWER_PROCESS_HH__ +#define __POWER_PROCESS_HH__ + +#include <string> +#include <vector> +#include "sim/process.hh" + +class LiveProcess; +class ObjectFile; +class System; + +class PowerLiveProcess : public LiveProcess +{ + protected: + PowerLiveProcess(LiveProcessParams * params, ObjectFile *objFile); + + void startup(); + + public: + void argsInit(int intSize, int pageSize); + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i); + void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); +}; + +#endif // __POWER_PROCESS_HH__ + diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh new file mode 100644 index 000000000..5bcca3641 --- /dev/null +++ b/src/arch/power/registers.hh @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_REGISTERS_HH__ +#define __ARCH_POWER_REGISTERS_HH__ + +#include "arch/power/max_inst_regs.hh" +#include "arch/power/miscregs.hh" + +namespace PowerISA { + +using PowerISAInst::MaxInstSrcRegs; +using PowerISAInst::MaxInstDestRegs; + +typedef uint8_t RegIndex; + +typedef uint64_t IntReg; + +// Floating point register file entry type +typedef uint64_t FloatRegBits; +typedef double FloatReg; +typedef uint64_t MiscReg; + +// Constants Related to the number of registers +const int NumIntArchRegs = 32; + +// CR, XER, LR, CTR, FPSCR, RSV, RSV-LEN, RSV-ADDR +// and zero register, which doesn't actually exist but needs a number +const int NumIntSpecialRegs = 9; +const int NumFloatArchRegs = 32; +const int NumFloatSpecialRegs = 0; +const int NumInternalProcRegs = 0; + +const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; +const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs; +const int NumMiscRegs = NUM_MISCREGS; + +// Semantically meaningful register indices +const int ReturnValueReg = 3; +const int ArgumentReg0 = 3; +const int ArgumentReg1 = 4; +const int ArgumentReg2 = 5; +const int ArgumentReg3 = 6; +const int ArgumentReg4 = 7; +const int FramePointerReg = 31; +const int StackPointerReg = 1; + +// There isn't one in Power, but we need to define one somewhere +const int ZeroReg = NumIntRegs - 1; + +const int SyscallNumReg = 0; +const int SyscallPseudoReturnReg = 3; +const int SyscallSuccessReg = 3; + +// These help enumerate all the registers for dependence tracking. +const int FP_Base_DepTag = NumIntRegs; +const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs; + +typedef union { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; +} AnyReg; + +enum MiscIntRegNums { + INTREG_CR = NumIntArchRegs, + INTREG_XER, + INTREG_LR, + INTREG_CTR, + INTREG_FPSCR, + INTREG_RSV, + INTREG_RSV_LEN, + INTREG_RSV_ADDR +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_REGISTERS_HH__ diff --git a/src/mem/slicc/ast/TypeAST.hh b/src/arch/power/remote_gdb.hh index f8e1fdc24..34bb4bd1f 100644 --- a/src/mem/slicc/ast/TypeAST.hh +++ b/src/arch/power/remote_gdb.hh @@ -1,6 +1,7 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,59 +26,59 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeAST.hh - * - * Description: - * - * $Id: TypeAST.hh,v 3.2 2003/03/22 15:15:17 xu Exp $ * + * Authors: Nathan Binkert + * Stephen Hines + * Timothy M. Jones */ -#ifndef TYPEAST_H -#define TYPEAST_H +#ifndef __ARCH_ARM_REMOTE_GDB_HH__ +#define __ARCH_ARM_REMOTE_GDB_HH__ -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" +#include "base/remote_gdb.hh" -class TypeAST : public AST { -public: - // Constructors - TypeAST(string* ident_ptr); - - // Destructor - ~TypeAST(); +namespace PowerISA +{ - // Public Methods - string toString() const; - Type* lookupType() const; +class RemoteGDB : public BaseRemoteGDB +{ + public: + RemoteGDB(System *system, ThreadContext *context) + : BaseRemoteGDB(system, context, 1) + { + } - virtual void print(ostream& out) const {} -private: - // Private Methods + bool + acc(Addr, size_t) + { + panic("acc not implemented for POWER!"); + } - // Private copy constructor and assignment operator - TypeAST(const TypeAST& obj); - TypeAST& operator=(const TypeAST& obj); + void + getregs() + { + panic("getregs not implemented for POWER!"); + } - // Data Members (m_ prefix) - string* m_ident_ptr; -}; + void + setregs() + { + panic("setregs not implemented for POWER!"); + } -// Output operator declaration -ostream& operator<<(ostream& out, const TypeAST& obj); + void + clearSingleStep() + { + panic("clearSingleStep not implemented for POWER!"); + } -// ******************* Definitions ******************* + void + setSingleStep() + { + panic("setSingleStep not implemented for POWER!"); + } +}; -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeAST& obj) -{ - obj.print(out); - out << flush; - return out; -} +} // PowerISA namespace -#endif //TYPEAST_H +#endif /* __ARCH_POWER_REMOTE_GDB_H__ */ diff --git a/src/arch/power/stacktrace.hh b/src/arch/power/stacktrace.hh new file mode 100644 index 000000000..49d687a6e --- /dev/null +++ b/src/arch/power/stacktrace.hh @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_STACKTRACE_HH__ +#define __ARCH_POWER_STACKTRACE_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +class ThreadContext; +class StackTrace; + +namespace PowerISA +{ + +class ProcessInfo +{ + private: + ThreadContext *tc; + + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; + + public: + ProcessInfo(ThreadContext *_tc); + + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; +}; + +class StackTrace +{ + protected: + typedef TheISA::MachInst MachInst; + private: + ThreadContext *tc; + std::vector<Addr> stack; + + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); + + void trace(ThreadContext *tc, bool is_call); + + public: + StackTrace(); + StackTrace(ThreadContext *tc, StaticInstPtr inst); + ~StackTrace(); + + void + clear() + { + tc = 0; + stack.clear(); + } + + bool + valid() const + { + return tc != NULL; + } + + bool trace(ThreadContext *tc, StaticInstPtr inst); + + public: + const std::vector<Addr> & + getstack() const + { + return stack; + } + + static const int user = 1; + static const int console = 2; + static const int unknown = 3; + +#if TRACING_ON + private: + void dump(); + + public: + void + dprintf() + { + if (DTRACE(Stack)) + dump(); + } +#else + public: + void + dprintf() + { + } +#endif +}; + +inline bool +StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) +{ + if (!inst->isCall() && !inst->isReturn()) + return false; + + if (valid()) + clear(); + + trace(tc, !inst->isReturn()); + return true; +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_STACKTRACE_HH__ diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc new file mode 100644 index 000000000..125c92a1a --- /dev/null +++ b/src/arch/power/tlb.cc @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Jaidev Patwardhan + * Stephen Hines + * Timothy M. Jones + */ + +#include <string> +#include <vector> + +#include "arch/power/faults.hh" +#include "arch/power/pagetable.hh" +#include "arch/power/tlb.hh" +#include "arch/power/utility.hh" +#include "base/inifile.hh" +#include "base/str.hh" +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "mem/page_table.hh" +#include "params/PowerTLB.hh" +#include "sim/process.hh" + + +using namespace std; +using namespace PowerISA; + +/////////////////////////////////////////////////////////////////////// +// +// POWER TLB +// + +#define MODE2MASK(X) (1 << (X)) + +TLB::TLB(const Params *p) + : BaseTLB(p), size(p->size), nlu(0) +{ + table = new PowerISA::PTE[size]; + memset(table, 0, sizeof(PowerISA::PTE[size])); + smallPages = 0; +} + +TLB::~TLB() +{ + if (table) + delete [] table; +} + +// look up an entry in the TLB +PowerISA::PTE * +TLB::lookup(Addr vpn, uint8_t asn) const +{ + // assume not found... + PowerISA::PTE *retval = NULL; + PageTable::const_iterator i = lookupTable.find(vpn); + if (i != lookupTable.end()) { + while (i->first == vpn) { + int index = i->second; + PowerISA::PTE *pte = &table[index]; + Addr Mask = pte->Mask; + Addr InvMask = ~Mask; + Addr VPN = pte->VPN; + if (((vpn & InvMask) == (VPN & InvMask)) + && (pte->G || (asn == pte->asid))) { + + // We have a VPN + ASID Match + retval = pte; + break; + } + ++i; + } + } + + DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, + retval ? "hit" : "miss", retval ? retval->PFN1 : 0); + return retval; +} + +PowerISA::PTE* +TLB::getEntry(unsigned Index) const +{ + // Make sure that Index is valid + assert(Index<size); + return &table[Index]; +} + +int +TLB::probeEntry(Addr vpn,uint8_t asn) const +{ + // assume not found... + PowerISA::PTE *retval = NULL; + int Ind = -1; + PageTable::const_iterator i = lookupTable.find(vpn); + if (i != lookupTable.end()) { + while (i->first == vpn) { + int index = i->second; + PowerISA::PTE *pte = &table[index]; + Addr Mask = pte->Mask; + Addr InvMask = ~Mask; + Addr VPN = pte->VPN; + if (((vpn & InvMask) == (VPN & InvMask)) + && (pte->G || (asn == pte->asid))) { + + // We have a VPN + ASID Match + retval = pte; + Ind = index; + break; + } + ++i; + } + } + + DPRINTF(Power, "VPN: %x, asid: %d, Result of TLBP: %d\n", vpn, asn, Ind); + return Ind; +} + +inline Fault +TLB::checkCacheability(RequestPtr &req) +{ + Addr VAddrUncacheable = 0xA0000000; + if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { + + // mark request as uncacheable + req->setFlags(Request::UNCACHEABLE); + } + return NoFault; +} + +void +TLB::insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages) +{ + smallPages=_smallPages; + if (Index > size){ + warn("Attempted to write at index (%d) beyond TLB size (%d)", + Index, size); + } else { + + // Update TLB + if (table[Index].V0 == true || table[Index].V1 == true) { + + // Previous entry is valid + PageTable::iterator i = lookupTable.find(table[Index].VPN); + lookupTable.erase(i); + } + table[Index]=pte; + + // Update fast lookup table + lookupTable.insert(make_pair(table[Index].VPN, Index)); + } +} + +// insert a new TLB entry +void +TLB::insert(Addr addr, PowerISA::PTE &pte) +{ + fatal("TLB Insert not yet implemented\n"); +} + +void +TLB::flushAll() +{ + DPRINTF(TLB, "flushAll\n"); + memset(table, 0, sizeof(PowerISA::PTE[size])); + lookupTable.clear(); + nlu = 0; +} + +void +TLB::serialize(ostream &os) +{ + SERIALIZE_SCALAR(size); + SERIALIZE_SCALAR(nlu); + + for (int i = 0; i < size; i++) { + nameOut(os, csprintf("%s.PTE%d", name(), i)); + table[i].serialize(os); + } +} + +void +TLB::unserialize(Checkpoint *cp, const string §ion) +{ + UNSERIALIZE_SCALAR(size); + UNSERIALIZE_SCALAR(nlu); + + for (int i = 0; i < size; i++) { + table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); + if (table[i].V0 || table[i].V1) { + lookupTable.insert(make_pair(table[i].VPN, i)); + } + } +} + +void +TLB::regStats() +{ + read_hits + .name(name() + ".read_hits") + .desc("DTB read hits") + ; + + read_misses + .name(name() + ".read_misses") + .desc("DTB read misses") + ; + + + read_accesses + .name(name() + ".read_accesses") + .desc("DTB read accesses") + ; + + write_hits + .name(name() + ".write_hits") + .desc("DTB write hits") + ; + + write_misses + .name(name() + ".write_misses") + .desc("DTB write misses") + ; + + + write_accesses + .name(name() + ".write_accesses") + .desc("DTB write accesses") + ; + + hits + .name(name() + ".hits") + .desc("DTB hits") + ; + + misses + .name(name() + ".misses") + .desc("DTB misses") + ; + + invalids + .name(name() + ".invalids") + .desc("DTB access violations") + ; + + accesses + .name(name() + ".accesses") + .desc("DTB accesses") + ; + + hits = read_hits + write_hits; + misses = read_misses + write_misses; + accesses = read_accesses + write_accesses; +} + +Fault +TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) +{ +#if !FULL_SYSTEM + Process * p = tc->getProcessPtr(); + + Fault fault = p->pTable->translate(req); + if (fault != NoFault) + return fault; + + return NoFault; +#else + fatal("translate atomic not yet implemented\n"); +#endif +} + +void +TLB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, Mode mode) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, mode), req, tc, mode); +} + +PowerISA::PTE & +TLB::index(bool advance) +{ + PowerISA::PTE *pte = &table[nlu]; + + if (advance) + nextnlu(); + + return *pte; +} + +PowerISA::TLB * +PowerTLBParams::create() +{ + return new PowerISA::TLB(this); +} diff --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh new file mode 100644 index 000000000..8b6c7233d --- /dev/null +++ b/src/arch/power/tlb.hh @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_TLB_HH__ +#define __ARCH_POWER_TLB_HH__ + +#include <map> + +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" +#include "arch/power/vtophys.hh" +#include "arch/power/pagetable.hh" +#include "base/statistics.hh" +#include "mem/request.hh" +#include "params/PowerTLB.hh" +#include "sim/faults.hh" +#include "sim/tlb.hh" + +class ThreadContext; + +namespace PowerISA { + +// This is copied from the ARM ISA and has not been checked against the +// Power at all. +struct TlbEntry +{ + Addr _pageStart; + + TlbEntry() + { + } + + TlbEntry(Addr asn, Addr vaddr, Addr paddr) + : _pageStart(paddr) + { + } + + void + updateVaddr(Addr new_vaddr) + { + panic("unimplemented"); + } + + Addr + pageStart() + { + return _pageStart; + } + + void + serialize(std::ostream &os) + { + SERIALIZE_SCALAR(_pageStart); + } + + void + unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_SCALAR(_pageStart); + } +}; + +class TLB : public BaseTLB +{ + protected: + typedef std::multimap<Addr, int> PageTable; + PageTable lookupTable; // Quick lookup into page table + + PowerISA::PTE *table; // the Page Table + int size; // TLB Size + int nlu; // not last used entry (for replacement) + + void + nextnlu() + { + if (++nlu >= size) { + nlu = 0; + } + } + + PowerISA::PTE *lookup(Addr vpn, uint8_t asn) const; + + mutable Stats::Scalar read_hits; + mutable Stats::Scalar read_misses; + mutable Stats::Scalar read_acv; + mutable Stats::Scalar read_accesses; + mutable Stats::Scalar write_hits; + mutable Stats::Scalar write_misses; + mutable Stats::Scalar write_acv; + mutable Stats::Scalar write_accesses; + Stats::Formula hits; + Stats::Formula misses; + Stats::Formula invalids; + Stats::Formula accesses; + + public: + typedef PowerTLBParams Params; + TLB(const Params *p); + virtual ~TLB(); + + int probeEntry(Addr vpn,uint8_t) const; + PowerISA::PTE *getEntry(unsigned) const; + + int smallPages; + + int + getsize() const + { + return size; + } + + PowerISA::PTE &index(bool advance = true); + void insert(Addr vaddr, PowerISA::PTE &pte); + void insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages); + void flushAll(); + + void + demapPage(Addr vaddr, uint64_t asn) + { + panic("demapPage unimplemented.\n"); + } + + // static helper functions... really + static bool validVirtualAddress(Addr vaddr); + static Fault checkCacheability(RequestPtr &req); + Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, Mode mode); + + // Checkpointing + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + void regStats(); +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_TLB_HH__ diff --git a/src/mem/slicc/ast/ExprAST.hh b/src/arch/power/types.hh index 9566541da..7b994adc9 100644 --- a/src/mem/slicc/ast/ExprAST.hh +++ b/src/arch/power/types.hh @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 The University of Edinburgh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,60 +24,68 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ExprAST.hh - * - * Description: - * - * $Id$ * + * Authors: Timothy M. Jones */ -#ifndef EXPRAST_H -#define EXPRAST_H +#ifndef __ARCH_POWER_TYPES_HH__ +#define __ARCH_POWER_TYPES_HH__ -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" +#include "base/bitunion.hh" +#include "base/types.hh" +namespace PowerISA +{ -class ExprAST : public AST { -public: - // Constructors - ExprAST() : AST() { } +typedef uint32_t MachInst; - // Destructor - virtual ~ExprAST() { } +BitUnion32(ExtMachInst) - // Public Methods - virtual Type* generate(string& code) const = 0; - virtual void findResources(Map<Var*, string>& resource_list) const {} // The default is no resources + // Registers + Bitfield<25, 21> rs; + Bitfield<20, 16> ra; - // void print(ostream& out) const; -private: - // Private Methods + // Shifts and masks + Bitfield<15, 11> sh; + Bitfield<10, 6> mb; + Bitfield< 5, 1> me; - // Private copy constructor and assignment operator - // ExprAST(const ExprAST& obj); - // ExprAST& operator=(const ExprAST& obj); + // Immediate fields + Bitfield<15, 0> si; + Bitfield<15, 0> d; - // Data Members (m_ prefix) + // Special purpose register identifier + Bitfield<20, 11> spr; + Bitfield<25, 2> li; + Bitfield<1> aa; + Bitfield<25, 23> bf; + Bitfield<15, 2> bd; + Bitfield<25, 21> bo; + Bitfield<20, 16> bi; + Bitfield<20, 18> bfa; -}; + // Record bits + Bitfield<0> rc31; + Bitfield<10> oe; -// Output operator declaration -ostream& operator<<(ostream& out, const ExprAST& obj); + // Condition register fields + Bitfield<25, 21> bt; + Bitfield<20, 16> ba; + Bitfield<15, 11> bb; -// ******************* Definitions ******************* + // FXM field for mtcrf instruction + Bitfield<19, 12> fxm; +EndBitUnion(ExtMachInst) -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} +// typedef uint64_t LargestRead; +// // Need to use 64 bits to make sure that read requests get handled properly + +// typedef int RegContextParam; +// typedef int RegContextVal; + +struct CoreSpecific { +}; + +} // PowerISA namspace -#endif //EXPRAST_H +#endif // __ARCH_POWER_TYPES_HH__ diff --git a/src/arch/power/utility.hh b/src/arch/power/utility.hh new file mode 100644 index 000000000..442075aa2 --- /dev/null +++ b/src/arch/power/utility.hh @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Korey Sewell + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_UTILITY_HH__ +#define __ARCH_POWER_UTILITY_HH__ + +#include "arch/power/miscregs.hh" +#include "arch/power/types.hh" +#include "base/hashmap.hh" +#include "base/types.hh" +#include "cpu/thread_context.hh" + +namespace __hash_namespace { + +template<> +struct hash<PowerISA::ExtMachInst> : public hash<uint32_t> { + size_t operator()(const PowerISA::ExtMachInst &emi) const { + return hash<uint32_t>::operator()((uint32_t)emi); + }; +}; + +} // __hash_namespace namespace + +namespace PowerISA { + +/** + * Function to ensure ISA semantics about 0 registers. + * @param tc The thread context. + */ +template <class TC> +void zeroRegisters(TC *tc); + +// Instruction address compression hooks +static inline Addr +realPCToFetchPC(const Addr &addr) +{ + return addr; +} + +static inline Addr +fetchPCToRealPC(const Addr &addr) +{ + return addr; +} + +// the size of "fetched" instructions +static inline size_t +fetchInstSize() +{ + return sizeof(MachInst); +} + +static inline MachInst +makeRegisterCopy(int dest, int src) +{ + panic("makeRegisterCopy not implemented"); + return 0; +} + +inline void +startupCPU(ThreadContext *tc, int cpuId) +{ + tc->activate(0); +} + +template <class XC> +Fault +checkFpEnableFault(XC *xc) +{ + return NoFault; +} + +static inline void +copyRegs(ThreadContext *src, ThreadContext *dest) +{ + panic("Copy Regs Not Implemented Yet\n"); +} + +static inline void +copyMiscRegs(ThreadContext *src, ThreadContext *dest) +{ + panic("Copy Misc. Regs Not Implemented Yet\n"); +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_UTILITY_HH__ diff --git a/src/arch/power/vtophys.hh b/src/arch/power/vtophys.hh new file mode 100644 index 000000000..3cfebcfc7 --- /dev/null +++ b/src/arch/power/vtophys.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Nathan Binkert + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_VTOPHYS_HH__ +#define __ARCH_POWER_VTOPHYS_HH__ + +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" + + +class ThreadContext; +class FunctionalPort; + +namespace PowerISA { + +inline Addr +PteAddr(Addr a) +{ + return (a & PteMask) << PteShift; +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_VTOPHYS_HH__ + diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index e34ca033f..ce5e34ff0 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -226,7 +226,8 @@ decode OP default Unknown::unknown() if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; else Rd = Rs1.udw / Rs2_or_imm13.udw;}}); 0x1E: IntOpCcRes::udivcc({{ - uint32_t resTemp, val2 = Rs2_or_imm13.udw; + uint64_t resTemp; + uint32_t val2 = Rs2_or_imm13.udw; int32_t overflow = 0; if(val2 == 0) fault = new DivisionByZero; else diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index b1dc691ce..1f7567d43 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -77,6 +77,22 @@ class SparcLinux : public Linux static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x20; + + typedef struct { + int64_t uptime; /* Seconds since boot */ + uint64_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t sharedram; /* Amount of shared memory */ + uint64_t bufferram; /* Memory used by buffers */ + uint64_t totalswap; /* Total swap space size */ + uint64_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint64_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; class Sparc32Linux : public SparcLinux @@ -105,6 +121,22 @@ class Sparc32Linux : public SparcLinux uint32_t __unused4; uint32_t __unused5; } tgt_stat64; + + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; #endif diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index f4781d886..874ddc005 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -41,7 +41,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -59,9 +60,10 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { const IntReg id = htog(100); - Addr ruid = p->getSyscallArg(tc, 0); - Addr euid = p->getSyscallArg(tc, 1); - Addr suid = p->getSyscallArg(tc, 2); + int index = 0; + Addr ruid = p->getSyscallArg(tc, index); + Addr euid = p->getSyscallArg(tc, index); + Addr suid = p->getSyscallArg(tc, index); //Handle the EFAULT case //Set the ruid if(ruid) @@ -302,7 +304,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 211 */ SyscallDesc("tgkill", unimplementedFunc), //32 bit /* 212 */ SyscallDesc("waitpid", unimplementedFunc), //32 bit /* 213 */ SyscallDesc("swapoff", unimplementedFunc), - /* 214 */ SyscallDesc("sysinfo", unimplementedFunc), //32 bit + /* 214 */ SyscallDesc("sysinfo", sysinfoFunc<Sparc32Linux>), //32 bit /* 215 */ SyscallDesc("ipc", unimplementedFunc), //32 bit /* 216 */ SyscallDesc("sigreturn", unimplementedFunc), //32 bit /* 217 */ SyscallDesc("clone", cloneFunc), @@ -608,7 +610,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 211 */ SyscallDesc("tgkill", unimplementedFunc), /* 212 */ SyscallDesc("waitpid", unimplementedFunc), /* 213 */ SyscallDesc("swapoff", unimplementedFunc), - /* 214 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 214 */ SyscallDesc("sysinfo", sysinfoFunc<SparcLinux>), /* 215 */ SyscallDesc("ipc", unimplementedFunc), /* 216 */ SyscallDesc("sigreturn", unimplementedFunc), /* 217 */ SyscallDesc("clone", cloneFunc), diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 89e853573..7e01f6b07 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -514,10 +514,10 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc) } IntReg -Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int i) +Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return bits(tc->readIntReg(FirstArgumentReg + i), 31, 0); + return bits(tc->readIntReg(FirstArgumentReg + i++), 31, 0); } void @@ -528,10 +528,10 @@ Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val) } IntReg -Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return tc->readIntReg(FirstArgumentReg + i); + return tc->readIntReg(FirstArgumentReg + i++); } void diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index fdb9734ba..cca312e0a 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -95,7 +95,7 @@ class Sparc32LiveProcess : public SparcLiveProcess void flushWindows(ThreadContext *tc); - SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; @@ -123,7 +123,7 @@ class Sparc64LiveProcess : public SparcLiveProcess void flushWindows(ThreadContext *tc); - SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index eafb488df..24abd8687 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -48,7 +48,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Solaris::utsname> name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<Solaris::utsname> name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "SunOS"); strcpy(name->nodename, "m5.eecs.umich.edu"); diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py index 15b03fd33..9f7dc43b3 100644 --- a/src/arch/x86/X86TLB.py +++ b/src/arch/x86/X86TLB.py @@ -53,13 +53,14 @@ # # Authors: Gabe Black -from MemObject import MemObject +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env + from BaseTLB import BaseTLB +from MemObject import MemObject -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: class X86PagetableWalker(MemObject): type = 'X86PagetableWalker' cxx_class = 'X86ISA::Walker' @@ -70,6 +71,6 @@ class X86TLB(BaseTLB): type = 'X86TLB' cxx_class = 'X86ISA::TLB' size = Param.Int(64, "TLB size") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: walker = Param.X86PagetableWalker(\ X86PagetableWalker(), "page table walker") diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 1b7933036..1b83c6649 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -500,7 +500,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) InterruptCommandRegHigh high = regs[APIC_INTERRUPT_COMMAND_HIGH]; // Record that an IPI is being sent. low.deliveryStatus = 1; - TriggerIntMessage message; + TriggerIntMessage message = 0; message.destination = high.destination; message.vector = low.vector; message.deliveryMode = low.deliveryMode; diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc index 06a656efc..47d24ed1e 100644 --- a/src/arch/x86/isa.cc +++ b/src/arch/x86/isa.cc @@ -41,7 +41,7 @@ void ISA::updateHandyM5Reg(Efer efer, CR0 cr0, SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags) { - HandyM5Reg m5reg; + HandyM5Reg m5reg = 0; if (efer.lma) { m5reg.mode = LongMode; if (csAttr.longMode) diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index c23eeccab..288c5e5a8 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -604,7 +604,7 @@ } // repe (0xF3) 0x4: decode OPCODE_OP_BOTTOM3 { - 0x7: WarnUnimpl::movdqu_Vo_Wo(); + 0x7: MOVDQU(Vo,Wo); default: UD2(); } // operand size (0x66) @@ -615,8 +615,8 @@ 0x3: PACKSSDW(Vo,Wo); 0x4: PUNPCKLQDQ(Vo,Wq); 0x5: PUNPCKHQDQ(Vo,Wq); - 0x6: WarnUnimpl::movd_Vo_Ed(); - 0x7: WarnUnimpl::movdqa_Vo_Wo(); + 0x6: MOVD(Vo,Edp); + 0x7: MOVDQA(Vo,Wo); } default: UD2(); } @@ -673,9 +673,9 @@ //0x3: group14_pshimq(); 0x3: decode MODRM_REG { 0x2: PSRLQ(VRo,Ib); - 0x3: WarnUnimpl::psrldq_VRo_Ib(); + 0x3: PSRLDQ(VRo,Ib); 0x6: PSLLQ(VRo,Ib); - 0x7: WarnUnimpl::pslldq_VRo_Ib(); + 0x7: PSLLDQ(VRo,Ib); default: UD2(); } 0x4: PCMPEQB(Vo,Wo); @@ -702,15 +702,15 @@ // repe (0xF3) 0x4: decode OPCODE_OP_BOTTOM3 { 0x6: MOVQ(Vq,Wq); - 0x7: WarnUnimpl::movdqu_Wo_Vo(); + 0x7: MOVDQU(Wo,Vo); default: UD2(); } // operand size (0x66) 0x1: decode OPCODE_OP_BOTTOM3 { - 0x4: WarnUnimpl::haddpd_Vo_Wo(); + 0x4: HADDPD(Vo,Wo); 0x5: WarnUnimpl::hsubpd_Vo_Wo(); - 0x6: WarnUnimpl::movd_Ed_Vd(); - 0x7: WarnUnimpl::movdqa_Wo_Vo(); + 0x6: MOVD(Edp,Vd); + 0x7: MOVDQA(Wo,Vo); default: UD2(); } // repne (0xF2) diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index a9ad611b7..1c0650683 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -62,7 +62,7 @@ def macroop IRET_PROT { .adjust_env oszIn64Override # Check for a nested task. This isn't supported at the moment. - rflag t1, NT + rflag t1, 14; #NT bit panic "Task switching with iret is unimplemented!", flags=(nCEZF,) #t1 = temp_RIP diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 7ccdca6c3..51f5ad23b 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -355,6 +355,36 @@ def macroop MOVNTI_P_R { rdip t7 st reg, seg, riprel, disp }; + +def macroop MOVD_XMM_R { + mov2fp xmml, regm, srcSize=dsz, destSize=8 + lfpimm xmmh, 0 +}; + +def macroop MOVD_XMM_M { + ldfp xmml, seg, sib, disp, dataSize=dsz + lfpimm xmmh, 0 +}; + +def macroop MOVD_XMM_P { + rdip t7 + ldfp xmml, seg, riprel, disp, dataSize=dsz + lfpimm xmmh, 0 +}; + +def macroop MOVD_R_XMM { + mov2int reg, xmmlm, size=dsz +}; + +def macroop MOVD_M_XMM { + stfp xmml, seg, sib, disp, dataSize=dsz +}; + +def macroop MOVD_P_XMM { + rdip t7 + stfp xmml, seg, riprel, disp, dataSize=dsz +}; + ''' #let {{ # class MOVD(Inst): diff --git a/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py b/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py index 8b307d3da..adf7650b9 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py @@ -55,5 +55,25 @@ microcode = ''' # HADDPS -# HADDPD + +def macroop HADDPD_XMM_XMM { + maddf ufp1, xmmh , xmml, size=8, ext=1 + maddf xmmh, xmmlm, xmmhm, size=8, ext=1 + movfp xmml, ufp1 +}; + +def macroop HADDPD_XMM_M { + ldfp ufp1, seg, sib, disp, dataSize=8 + ldfp ufp2, seg, sib, "DISPLACEMENT+8", dataSize=8 + maddf xmml, xmmh, xmml, size=8, ext=1 + maddf xmmh, ufp1, ufp2, size=8, ext=1 +}; + +def macroop HADDPD_XMM_P { + rdip t7 + ldfp ufp1, seg, riprel, disp, dataSize=8 + ldfp ufp2, seg, riprel, "DISPLACEMENT+8", dataSize=8 + maddf xmml, xmmh, xmml, size=8, ext=1 + maddf xmmh, ufp1, ufp2, size=8, ext=1 +}; ''' diff --git a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py index 1f4044bde..86ac89ade 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py @@ -168,41 +168,39 @@ def macroop MOVUPD_P_XMM { }; def macroop MOVHPS_XMM_M { - ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPS_XMM_P { rdip t7 - ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVHPS_M_XMM { - stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPS_P_XMM { rdip t7 - stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 - stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVHPD_XMM_M { - ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPD_XMM_P { rdip t7 - ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVHPD_M_XMM { - stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPD_P_XMM { rdip t7 - stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 - stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVLPS_XMM_M { diff --git a/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py index c34bd42bb..ec80ffe73 100644 --- a/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py @@ -87,7 +87,59 @@ def macroop MOVQ2DQ_XMM_MMX { movfp xmml, mmxm, dataSize=8 lfpimm xmmh, 0 }; + +def macroop MOVDQA_XMM_XMM { + movfp xmml, xmmlm + movfp xmmh, xmmhm +}; + +def macroop MOVDQA_XMM_M { + ldfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQA_XMM_P { + rdip t7 + ldfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQA_M_XMM { + stfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQA_P_XMM { + rdip t7 + stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_XMM_XMM { + movfp xmml, xmmlm + movfp xmmh, xmmhm +}; + +def macroop MOVDQU_XMM_M { + ldfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_XMM_P { + rdip t7 + ldfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_M_XMM { + stfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_P_XMM { + rdip t7 + stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; ''' -# MOVDQA -# MOVDQU # LDDQU diff --git a/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py b/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py index 617033bc0..c13c7064c 100644 --- a/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py +++ b/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py @@ -122,5 +122,43 @@ def macroop PSLLQ_XMM_I { mslli xmml, xmml, imm, size=8, ext=0 mslli xmmh, xmmh, imm, size=8, ext=0 }; + +def macroop PSLLDQ_XMM_I { + + limm t2, 8 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("pslldq_less_8"), flags=(nCECF,) + + # Greater than 8 + + limm t2, 16 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("pslldq_less_16"), flags=(nCECF,) + + # Greater than 16 + + lfpimm xmml, 0 + lfpimm xmmh, 0 + br label("pslldq_end") + +pslldq_less_16: + + # Between 8 and 16 + + mslli xmmh, xmml, "(IMMEDIATE-8)<<3", size=8, ext=0 + lfpimm xmml, 0 + br label("pslldq_end") + +pslldq_less_8: + + # Less than 8 + + msrli ufp1, xmml, "(8-IMMEDIATE) << 3", size=8, ext=0 + mslli xmmh, xmmh, "IMMEDIATE << 3", size=8, ext=0 + mslli xmml, xmml, "IMMEDIATE << 3", size=8, ext=0 + mor xmmh, xmmh, ufp1 + +pslldq_end: + fault "NoFault" +}; ''' -# PSLLDQ diff --git a/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py b/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py index c904eaf50..61efe1a5d 100644 --- a/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py +++ b/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py @@ -122,5 +122,41 @@ def macroop PSRLQ_XMM_I { msrli xmml, xmml, imm, size=8, ext=0 msrli xmmh, xmmh, imm, size=8, ext=0 }; + +def macroop PSRLDQ_XMM_I { + limm t2, 8 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("psrldq_less_8"), flags=(nCECF,) + # Greater than 8 + + limm t2, 16 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("psrldq_less_16"), flags=(nCECF,) + + # Greater than 16 + + lfpimm xmml, 0 + lfpimm xmmh, 0 + br label("psrldq_end") + +psrldq_less_16: + + # Between 8 and 16 + + msrli xmml, xmmh, "(IMMEDIATE-8)<<3", size=8, ext=0 + lfpimm xmmh, 0 + br label("psrldq_end") + +psrldq_less_8: + + # Less than 8 + + mslli ufp1, xmmh, "(8-IMMEDIATE) << 3", size=8, ext=0 + msrli xmml, xmml, "IMMEDIATE << 3", size=8, ext=0 + msrli xmmh, xmmh, "IMMEDIATE << 3", size=8, ext=0 + mor xmml, xmml, ufp1 + +psrldq_end: + fault "NoFault" +}; ''' -# PSRLDQ diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py index b83fcba95..c97f2f152 100644 --- a/src/arch/x86/isa/insts/system/segmentation.py +++ b/src/arch/x86/isa/insts/system/segmentation.py @@ -179,7 +179,8 @@ def macroop LTR_R wrdh t3, t1, t2 wrdl tr, t1, reg wrbase tr, t3, dataSize=8 - ori t1, t1, (1 << 9) + limm t5, (1 << 9) + or t1, t1, t5 st t1, tsg, [8, t4, t0], dataSize=8 }; @@ -195,7 +196,8 @@ def macroop LTR_M wrdh t3, t1, t2 wrdl tr, t1, t5 wrbase tr, t3, dataSize=8 - ori t1, t1, (1 << 9) + limm t5, (1 << 9) + or t1, t1, t5 st t1, tsg, [8, t4, t0], dataSize=8 }; @@ -212,7 +214,8 @@ def macroop LTR_P wrdh t3, t1, t2 wrdl tr, t1, t5 wrbase tr, t3, dataSize=8 - ori t1, t1, (1 << 9) + limm t5, (1 << 9) + or t1, t1, t5 st t1, tsg, [8, t4, t0], dataSize=8 }; diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 912aa3511..afe1ead59 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -157,7 +157,7 @@ def template MicroLoadExecute {{ if (fault == NoFault) { %(code)s; - } else if (memFlags & Request::PF_EXCLUSIVE) { + } else if (memFlags & Request::PREFETCH) { // For prefetches, ignore any faults/exceptions. return NoFault; } @@ -374,7 +374,7 @@ let {{ if atCPL0: self.memFlags += " | (CPL0FlagBit << FlagShift)" if prefetch: - self.memFlags += " | Request::PF_EXCLUSIVE" + self.memFlags += " | Request::PREFETCH" self.memFlags += " | (machInst.legacy.addr ? " + \ "(AddrSizeFlagBit << FlagShift) : 0)" diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa index 9c53fa0fb..4052f254d 100644 --- a/src/arch/x86/isa/microops/mediaop.isa +++ b/src/arch/x86/isa/microops/mediaop.isa @@ -452,7 +452,7 @@ let {{ if (signBit) { if (overflow != mask(destBits - srcBits + 1)) { if (ext & 0x1) - picked = (1 << (destBits - 1)); + picked = (ULL(1) << (destBits - 1)); else picked = 0; } @@ -480,7 +480,7 @@ let {{ if (signBit) { if (overflow != mask(destBits - srcBits + 1)) { if (ext & 0x1) - picked = (1 << (destBits - 1)); + picked = (ULL(1) << (destBits - 1)); else picked = 0; } @@ -642,10 +642,10 @@ let {{ int loIndex = (i + 0) * sizeBits; uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (sizeBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (sizeBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); uint64_t resBits; if (ext & 0x2) { @@ -680,10 +680,10 @@ let {{ int loIndex = (i + 0) * sizeBits; uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (sizeBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (sizeBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); uint64_t resBits; if (ext & 0x2) { @@ -957,7 +957,7 @@ let {{ int resSign = bits(resBits, sizeBits - 1); if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { if (resSign == 0) - resBits = (1 << (sizeBits - 1)); + resBits = (ULL(1) << (sizeBits - 1)); else resBits = mask(sizeBits - 1); } @@ -996,7 +996,7 @@ let {{ int resSign = bits(resBits, sizeBits - 1); if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { if (resSign == 0) - resBits = (1 << (sizeBits - 1)); + resBits = (ULL(1) << (sizeBits - 1)); else resBits = mask(sizeBits - 1); } @@ -1032,16 +1032,16 @@ let {{ if (ext & 0x2) { int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (srcBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (srcBits - 1)))); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (srcBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (srcBits - 1)))); resBits = (uint64_t)(arg1 * arg2); } else { resBits = arg1Bits * arg2Bits; } if (ext & 0x4) - resBits += (1 << (destBits - 1)); + resBits += (ULL(1) << (destBits - 1)); if (ext & 0x8) resBits >>= destBits; @@ -1142,7 +1142,7 @@ let {{ } else { resBits = (arg1Bits >> shiftAmt); resBits = resBits | - (0 - (resBits & (1 << (sizeBits - 1 - shiftAmt)))); + (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt)))); } result = insertBits(result, hiIndex, loIndex, resBits); @@ -1237,7 +1237,7 @@ let {{ } if (destSize == 4) { - argBits = (uint32_t)(float)arg; + argBits = (uint32_t)arg; } else { argBits = (uint64_t)arg; } @@ -1289,7 +1289,8 @@ let {{ int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1; int srcLoIndex = srcStart + (i + 0) * srcSizeBits; uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex); - int64_t sArg = argBits | (0 - (argBits & (1 << srcHiIndex))); + + int64_t sArg = argBits | (0 - (argBits & (ULL(1) << srcHiIndex))); double arg = sArg; if (destSize == 4) { @@ -1400,10 +1401,10 @@ let {{ int loIndex = (i + 0) * sizeBits; uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (sizeBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (sizeBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); uint64_t resBits = 0; if (((ext & 0x2) == 0 && arg1 == arg2) || diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index a4cb6f4cc..0b1f9a96a 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -149,12 +149,12 @@ def template MicroRegOpImmDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(BasicExecDeclare)s @@ -203,7 +203,7 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, @@ -216,7 +216,7 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, @@ -324,11 +324,12 @@ let {{ matcher.sub(src2_name, flag_code), matcher.sub(src2_name, cond_check), matcher.sub(src2_name, else_code)) + imm_name = "%simm8" % match.group("prefix") self.buildCppClasses(name + "i", Name, suffix + "Imm", - matcher.sub("imm8", code), - matcher.sub("imm8", flag_code), - matcher.sub("imm8", cond_check), - matcher.sub("imm8", else_code)) + matcher.sub(imm_name, code), + matcher.sub(imm_name, flag_code), + matcher.sub(imm_name, cond_check), + matcher.sub(imm_name, else_code)) return # If there's something optional to do with flags, generate @@ -353,13 +354,16 @@ let {{ matcher = re.compile("(?<!\w)spsrc2(?!\w)") if matcher.search(allCode): code = "int64_t spsrc2 = signedPick(SrcReg2, 1, dataSize);" + code + matcher = re.compile("(?<!\w)simm8(?!\w)") + if matcher.search(allCode): + code = "int8_t simm8 = imm8;" + code base = "X86ISA::RegOp" # If imm8 shows up in the code, use the immediate templates, if # not, hopefully the register ones will be correct. templates = regTemplates - matcher = re.compile("(?<!\w)imm8(?!\w)") + matcher = re.compile("(?<!\w)s?imm8(?!\w)") if matcher.search(allCode): base += "Imm" templates = immTemplates @@ -521,7 +525,7 @@ let {{ code = ''' ProdLow = psrc1 * op2; int halfSize = (dataSize * 8) / 2; - uint64_t shifter = (1ULL << halfSize); + uint64_t shifter = (ULL(1) << halfSize); uint64_t hiResult; uint64_t psrc1_h = psrc1 / shifter; uint64_t psrc1_l = psrc1 & mask(halfSize); @@ -549,7 +553,7 @@ let {{ code = ''' ProdLow = psrc1 * op2; int halfSize = (dataSize * 8) / 2; - uint64_t shifter = (1ULL << halfSize); + uint64_t shifter = (ULL(1) << halfSize); uint64_t psrc1_h = psrc1 / shifter; uint64_t psrc1_l = psrc1 & mask(halfSize); uint64_t psrc2_h = (op2 / shifter) & mask(halfSize); diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index c2941c769..238b5e683 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -111,6 +111,22 @@ class X86Linux64 : public Linux uint64_t iov_base; // void * uint64_t iov_len; // size_t } tgt_iovec; + + typedef struct { + int64_t uptime; /* Seconds since boot */ + uint64_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t sharedram; /* Amount of shared memory */ + uint64_t bufferram; /* Memory used by buffers */ + uint64_t totalswap; /* Total swap space size */ + uint64_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint64_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; class X86Linux32 : public Linux @@ -126,8 +142,8 @@ class X86Linux32 : public Linux uint32_t st_uid; uint32_t st_gid; uint64_t st_rdev; - int64_t st_size; uint8_t __pad3[4]; + int64_t st_size; uint32_t st_blksize; uint64_t st_blocks; uint32_t st_atimeX; @@ -137,7 +153,7 @@ class X86Linux32 : public Linux uint32_t st_ctimeX; uint32_t st_ctime_nsec; uint64_t st_ino; - } tgt_stat64; + } __attribute__((__packed__)) tgt_stat64; static OpenFlagTransTable openFlagTable[]; @@ -160,6 +176,23 @@ class X86Linux32 : public Linux static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x20; + + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + + static bool mmapGrowsDown() { return true; } }; #endif diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 4d7bca95c..6a659108f 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -68,7 +68,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -94,8 +95,9 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, }; //First argument is the code, second is the address - int code = process->getSyscallArg(tc, 0); - uint64_t addr = process->getSyscallArg(tc, 1); + int index = 0; + int code = process->getSyscallArg(tc, index); + uint64_t addr = process->getSyscallArg(tc, index); uint64_t fsBase, gsBase; TranslatingPort *p = tc->getMemPort(); switch(code) @@ -159,7 +161,8 @@ setThreadArea32Func(SyscallDesc *desc, int callnum, assert((maxTLSEntry + 1) * sizeof(uint64_t) <= x86lp->gdtSize()); - TypedBufferArg<UserDesc32> userDesc(process->getSyscallArg(tc, 0)); + int argIndex = 0; + TypedBufferArg<UserDesc32> userDesc(process->getSyscallArg(tc, argIndex)); TypedBufferArg<uint64_t> gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t), numTLSEntries * sizeof(uint64_t)); @@ -232,7 +235,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 1 */ SyscallDesc("write", writeFunc), /* 2 */ SyscallDesc("open", openFunc<X86Linux64>), /* 3 */ SyscallDesc("close", closeFunc), - /* 4 */ SyscallDesc("stat", unimplementedFunc), + /* 4 */ SyscallDesc("stat", stat64Func<X86Linux64>), /* 5 */ SyscallDesc("fstat", fstat64Func<X86Linux64>), /* 6 */ SyscallDesc("lstat", unimplementedFunc), /* 7 */ SyscallDesc("poll", unimplementedFunc), @@ -241,7 +244,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 10 */ SyscallDesc("mprotect", unimplementedFunc), /* 11 */ SyscallDesc("munmap", munmapFunc), /* 12 */ SyscallDesc("brk", brkFunc), - /* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc), + /* 13 */ SyscallDesc("rt_sigaction", ignoreFunc), /* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc), /* 16 */ SyscallDesc("ioctl", unimplementedFunc), @@ -304,8 +307,8 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 73 */ SyscallDesc("flock", unimplementedFunc), /* 74 */ SyscallDesc("fsync", unimplementedFunc), /* 75 */ SyscallDesc("fdatasync", unimplementedFunc), - /* 76 */ SyscallDesc("truncate", unimplementedFunc), - /* 77 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 76 */ SyscallDesc("truncate", truncateFunc), + /* 77 */ SyscallDesc("ftruncate", ftruncateFunc), /* 78 */ SyscallDesc("getdents", unimplementedFunc), /* 79 */ SyscallDesc("getcwd", unimplementedFunc), /* 80 */ SyscallDesc("chdir", unimplementedFunc), @@ -327,7 +330,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 96 */ SyscallDesc("gettimeofday", unimplementedFunc), /* 97 */ SyscallDesc("getrlimit", unimplementedFunc), /* 98 */ SyscallDesc("getrusage", unimplementedFunc), - /* 99 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 99 */ SyscallDesc("sysinfo", sysinfoFunc<X86Linux64>), /* 100 */ SyscallDesc("times", unimplementedFunc), /* 101 */ SyscallDesc("ptrace", unimplementedFunc), /* 102 */ SyscallDesc("getuid", getuidFunc), @@ -429,7 +432,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 198 */ SyscallDesc("lremovexattr", unimplementedFunc), /* 199 */ SyscallDesc("fremovexattr", unimplementedFunc), /* 200 */ SyscallDesc("tkill", unimplementedFunc), - /* 201 */ SyscallDesc("time", unimplementedFunc), + /* 201 */ SyscallDesc("time", timeFunc<X86Linux64>), /* 202 */ SyscallDesc("futex", ignoreFunc), /* 203 */ SyscallDesc("sched_setaffinity", unimplementedFunc), /* 204 */ SyscallDesc("sched_getaffinity", unimplementedFunc), @@ -508,19 +511,19 @@ const int X86_64LinuxProcess::numSyscalls = SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc), - /* 1 */ SyscallDesc("exit", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), /* 2 */ SyscallDesc("fork", unimplementedFunc), - /* 3 */ SyscallDesc("read", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), /* 4 */ SyscallDesc("write", writeFunc), - /* 5 */ SyscallDesc("open", openFunc<X86Linux64>), - /* 6 */ SyscallDesc("close", unimplementedFunc), + /* 5 */ SyscallDesc("open", openFunc<X86Linux32>), + /* 6 */ SyscallDesc("close", closeFunc), /* 7 */ SyscallDesc("waitpid", unimplementedFunc), /* 8 */ SyscallDesc("creat", unimplementedFunc), /* 9 */ SyscallDesc("link", unimplementedFunc), /* 10 */ SyscallDesc("unlink", unimplementedFunc), /* 11 */ SyscallDesc("execve", unimplementedFunc), /* 12 */ SyscallDesc("chdir", unimplementedFunc), - /* 13 */ SyscallDesc("time", unimplementedFunc), + /* 13 */ SyscallDesc("time", timeFunc<X86Linux32>), /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 16 */ SyscallDesc("lchown", unimplementedFunc), @@ -531,7 +534,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 21 */ SyscallDesc("mount", unimplementedFunc), /* 22 */ SyscallDesc("umount", unimplementedFunc), /* 23 */ SyscallDesc("setuid", unimplementedFunc), - /* 24 */ SyscallDesc("getuid", unimplementedFunc), + /* 24 */ SyscallDesc("getuid", getuidFunc), /* 25 */ SyscallDesc("stime", unimplementedFunc), /* 26 */ SyscallDesc("ptrace", unimplementedFunc), /* 27 */ SyscallDesc("alarm", unimplementedFunc), @@ -554,10 +557,10 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 44 */ SyscallDesc("prof", unimplementedFunc), /* 45 */ SyscallDesc("brk", brkFunc), /* 46 */ SyscallDesc("setgid", unimplementedFunc), - /* 47 */ SyscallDesc("getgid", unimplementedFunc), + /* 47 */ SyscallDesc("getgid", getgidFunc), /* 48 */ SyscallDesc("signal", unimplementedFunc), - /* 49 */ SyscallDesc("geteuid", unimplementedFunc), - /* 50 */ SyscallDesc("getegid", unimplementedFunc), + /* 49 */ SyscallDesc("geteuid", geteuidFunc), + /* 50 */ SyscallDesc("getegid", getegidFunc), /* 51 */ SyscallDesc("acct", unimplementedFunc), /* 52 */ SyscallDesc("umount2", unimplementedFunc), /* 53 */ SyscallDesc("lock", unimplementedFunc), @@ -598,9 +601,9 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 88 */ SyscallDesc("reboot", unimplementedFunc), /* 89 */ SyscallDesc("readdir", unimplementedFunc), /* 90 */ SyscallDesc("mmap", unimplementedFunc), - /* 91 */ SyscallDesc("munmap", unimplementedFunc), - /* 92 */ SyscallDesc("truncate", unimplementedFunc), - /* 93 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 91 */ SyscallDesc("munmap", munmapFunc), + /* 92 */ SyscallDesc("truncate", truncateFunc), + /* 93 */ SyscallDesc("ftruncate", ftruncateFunc), /* 94 */ SyscallDesc("fchmod", unimplementedFunc), /* 95 */ SyscallDesc("fchown", unimplementedFunc), /* 96 */ SyscallDesc("getpriority", unimplementedFunc), @@ -623,7 +626,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 113 */ SyscallDesc("vm86old", unimplementedFunc), /* 114 */ SyscallDesc("wait4", unimplementedFunc), /* 115 */ SyscallDesc("swapoff", unimplementedFunc), - /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", sysinfoFunc<X86Linux32>), /* 117 */ SyscallDesc("ipc", unimplementedFunc), /* 118 */ SyscallDesc("fsync", unimplementedFunc), /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), @@ -681,7 +684,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 171 */ SyscallDesc("getresgid", unimplementedFunc), /* 172 */ SyscallDesc("prctl", unimplementedFunc), /* 173 */ SyscallDesc("rt_sigreturn", unimplementedFunc), - /* 174 */ SyscallDesc("rt_sigaction", unimplementedFunc), + /* 174 */ SyscallDesc("rt_sigaction", ignoreFunc), /* 175 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc), /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), @@ -700,16 +703,16 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 190 */ SyscallDesc("vfork", unimplementedFunc), /* 191 */ SyscallDesc("ugetrlimit", unimplementedFunc), /* 192 */ SyscallDesc("mmap2", mmapFunc<X86Linux32>), - /* 193 */ SyscallDesc("truncate64", unimplementedFunc), - /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc), - /* 195 */ SyscallDesc("stat64", unimplementedFunc), + /* 193 */ SyscallDesc("truncate64", truncate64Func), + /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func), + /* 195 */ SyscallDesc("stat64", stat64Func<X86Linux32>), /* 196 */ SyscallDesc("lstat64", unimplementedFunc), /* 197 */ SyscallDesc("fstat64", fstat64Func<X86Linux32>), /* 198 */ SyscallDesc("lchown32", unimplementedFunc), - /* 199 */ SyscallDesc("getuid32", unimplementedFunc), - /* 200 */ SyscallDesc("getgid32", unimplementedFunc), - /* 201 */ SyscallDesc("geteuid32", unimplementedFunc), - /* 202 */ SyscallDesc("getegid32", unimplementedFunc), + /* 199 */ SyscallDesc("getuid32", getuidFunc), + /* 200 */ SyscallDesc("getgid32", getgidFunc), + /* 201 */ SyscallDesc("geteuid32", geteuidFunc), + /* 202 */ SyscallDesc("getegid32", getegidFunc), /* 203 */ SyscallDesc("setreuid32", unimplementedFunc), /* 204 */ SyscallDesc("setregid32", unimplementedFunc), /* 205 */ SyscallDesc("getgroups32", unimplementedFunc), diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc index 5f2b5c421..e8c838dfb 100644 --- a/src/arch/x86/predecoder_tables.cc +++ b/src/arch/x86/predecoder_tables.cc @@ -191,7 +191,7 @@ namespace X86ISA /* 7 */ BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, /* 8 */ BY, ZW, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -/* A */ BY, VW, BY, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , +/* A */ VW, VW, VW, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , /* B */ BY, BY, BY, BY, BY, BY, BY, BY, VW, VW, VW, VW, VW, VW, VW, VW, /* C */ BY, BY, WO, 0 , 0 , 0 , BY, ZW, EN, 0 , WO, 0 , 0 , BY, 0 , 0 , /* D */ 0 , 0 , 0 , 0 , BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 4082e568c..42ca7b27d 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -139,6 +139,12 @@ X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params, int _numSyscallDescs) : X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs) { + + vsyscallPage.base = 0xffffffffff600000ULL; + vsyscallPage.size = VMPageSize; + vsyscallPage.vtimeOffset = 0x400; + vsyscallPage.vgettimeofdayOffset = 0x410; + // Set up stack. On X86_64 Linux, stack goes from the top of memory // downward, less the hole for the kernel address space plus one page // for undertermined purposes. @@ -169,7 +175,7 @@ I386LiveProcess::I386LiveProcess(LiveProcessParams *params, int _numSyscallDescs) : X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs) { - _gdtStart = 0x100000000; + _gdtStart = ULL(0x100000000); _gdtSize = VMPageSize; vsyscallPage.base = 0xffffe000ULL; @@ -184,7 +190,7 @@ I386LiveProcess::I386LiveProcess(LiveProcessParams *params, // Set up region for mmaps. This was determined empirically and may not // always be correct. - mmap_start = mmap_end = (Addr)0xf7ffd000ULL; + mmap_start = mmap_end = (Addr)0xf7ffe000ULL; } SyscallDesc* @@ -205,6 +211,24 @@ X86_64LiveProcess::startup() argsInit(sizeof(uint64_t), VMPageSize); + // Set up the vsyscall page for this process. + pTable->allocate(vsyscallPage.base, vsyscallPage.size); + uint8_t vtimeBlob[] = { + 0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00, // mov $0xc9,%rax + 0x0f,0x05, // syscall + 0xc3 // retq + }; + initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset, + vtimeBlob, sizeof(vtimeBlob)); + + uint8_t vgettimeofdayBlob[] = { + 0x48,0xc7,0xc0,0x60,0x00,0x00,0x00, // mov $0x60,%rax + 0x0f,0x05, // syscall + 0xc3 // retq + }; + initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vgettimeofdayOffset, + vgettimeofdayBlob, sizeof(vgettimeofdayBlob)); + for (int i = 0; i < contextIds.size(); i++) { ThreadContext * tc = system->getThreadContext(contextIds[i]); @@ -698,10 +722,10 @@ X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value) } X86ISA::IntReg -X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < NumArgumentRegs); - return tc->readIntReg(ArgumentReg[i]); + return tc->readIntReg(ArgumentReg[i++]); } void @@ -712,10 +736,21 @@ X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) } X86ISA::IntReg -I386LiveProcess::getSyscallArg(ThreadContext *tc, int i) +I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < NumArgumentRegs32); - return tc->readIntReg(ArgumentReg32[i]); + return tc->readIntReg(ArgumentReg32[i++]); +} + +X86ISA::IntReg +I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width) +{ + assert(width == 32 || width == 64); + assert(i < NumArgumentRegs); + uint64_t retVal = tc->readIntReg(ArgumentReg32[i++]) & mask(32); + if (width == 64) + retVal |= ((uint64_t)tc->readIntReg(ArgumentReg[i++]) << 32); + return retVal; } void diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index cd6d99e66..3ad2abe08 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -101,11 +101,21 @@ namespace X86ISA X86_64LiveProcess(LiveProcessParams *params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs); + class VSyscallPage + { + public: + Addr base; + Addr size; + Addr vtimeOffset; + Addr vgettimeofdayOffset; + }; + VSyscallPage vsyscallPage; + public: void argsInit(int intSize, int pageSize); void startup(); - X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; @@ -130,7 +140,8 @@ namespace X86ISA void startup(); void syscall(int64_t callnum, ThreadContext *tc); - X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i); + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width); void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; } diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc index 1594cc375..31183f2f9 100644 --- a/src/arch/x86/system.cc +++ b/src/arch/x86/system.cc @@ -211,7 +211,7 @@ X86System::startup() numGDTEntries++; - SegSelector ds; + SegSelector ds = 0; ds.si = numGDTEntries - 1; tc->setMiscReg(MISCREG_DS, (MiscReg)ds); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 5280b9ba8..d7959da2c 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -632,12 +632,26 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, Process *p = tc->getProcessPtr(); TlbEntry newEntry; bool success = p->pTable->lookup(vaddr, newEntry); - if(!success && mode != Execute) { + if (!success && mode != Execute) { p->checkAndAllocNextPage(vaddr); success = p->pTable->lookup(vaddr, newEntry); } - if(!success) { - panic("Tried to execute unmapped address %#x.\n", vaddr); + if (!success) { + if (req->isPrefetch()) { + return new PageFault(vaddr, true, mode, true, false); + } else { + const char *modeStr = ""; + if (mode == Execute) + modeStr = "execute"; + else if (mode == Read) + modeStr = "read"; + else if (mode == Write) + modeStr = "write"; + else + modeStr = "?"; + panic("Tried to %s unmapped address %#x.\n", + modeStr, vaddr); + } } else { Addr alignedVaddr = p->pTable->pageAlign(vaddr); DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, diff --git a/src/base/bigint.cc b/src/base/bigint.cc index ce9942c9c..d741e1f7b 100644 --- a/src/base/bigint.cc +++ b/src/base/bigint.cc @@ -28,10 +28,10 @@ * Authors: Gabe Black */ -#include "base/bigint.hh" - #include <iostream> +#include "base/bigint.hh" + using namespace std; ostream & operator << (ostream & os, const Twin64_t & t) diff --git a/src/base/bigint.hh b/src/base/bigint.hh index d60684231..a4e8738d3 100644 --- a/src/base/bigint.hh +++ b/src/base/bigint.hh @@ -28,10 +28,11 @@ * Authors: Ali Saidi */ -#include "base/misc.hh" - #include <iostream> +#include "base/misc.hh" +#include "base/types.hh" + #ifndef __BASE_BIGINT_HH__ #define __BASE_BIGINT_HH__ // Create a couple of large int types for atomic reads diff --git a/src/base/cp_annotate.cc b/src/base/cp_annotate.cc index 0aba2d999..4e138a6dd 100644 --- a/src/base/cp_annotate.cc +++ b/src/base/cp_annotate.cc @@ -35,6 +35,7 @@ #include "base/loader/object_file.hh" #include "base/output.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "sim/arguments.hh" #include "sim/core.hh" diff --git a/src/base/cp_annotate.hh b/src/base/cp_annotate.hh index 05d8129d0..4248c070a 100644 --- a/src/base/cp_annotate.hh +++ b/src/base/cp_annotate.hh @@ -41,6 +41,7 @@ #include "base/trace.hh" #include "base/types.hh" #include "config/cp_annotate.hh" +#include "config/the_isa.hh" #include "sim/serialize.hh" #include "sim/startup.hh" #include "sim/system.hh" diff --git a/src/base/inet.cc b/src/base/inet.cc index 898a189ef..1a280e993 100644 --- a/src/base/inet.cc +++ b/src/base/inet.cc @@ -28,6 +28,7 @@ * Authors: Nathan Binkert */ +#include <cstdio> #include <sstream> #include <string> diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 15ad88f76..60f0f99b4 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -97,6 +97,19 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) arch = ObjectFile::Alpha; } else if (ehdr.e_machine == EM_ARM) { arch = ObjectFile::Arm; + } else if (ehdr.e_machine == EM_PPC && + ehdr.e_ident[EI_CLASS] == ELFCLASS32) { + if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) { + arch = ObjectFile::Power; + } else { + fatal("The binary you're trying to load is compiled for " + "little endian Power.\nM5 only supports big " + "endian Power. Please recompile your binary.\n"); + } + } else if (ehdr.e_machine == EM_PPC64) { + fatal("The binary you're trying to load is compiled for 64-bit " + "Power. M5\n only supports 32-bit Power. Please " + "recompile your binary.\n"); } else { warn("Unknown architecture: %d\n", ehdr.e_machine); arch = ObjectFile::UnknownArch; diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh index e511451b7..b08f1c633 100644 --- a/src/base/loader/object_file.hh +++ b/src/base/loader/object_file.hh @@ -52,7 +52,8 @@ class ObjectFile Mips, X86_64, I386, - Arm + Arm, + Power }; enum OpSys { diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 6c301b10e..68747b3d1 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -118,6 +118,7 @@ #include <sys/signal.h> +#include <cstdio> #include <string> #include <unistd.h> @@ -131,9 +132,9 @@ #include "base/remote_gdb.hh" #include "base/socket.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/static_inst.hh" -//#include "mem/physical.hh" #include "mem/port.hh" #include "mem/translating_port.hh" #include "sim/system.hh" diff --git a/src/base/types.hh b/src/base/types.hh index 1a6db9fbb..0c10fac64 100644 --- a/src/base/types.hh +++ b/src/base/types.hh @@ -55,6 +55,7 @@ typedef int64_t Counter; * @note using an unsigned breaks the cache. */ typedef int64_t Tick; +typedef uint64_t UTick; const Tick MaxTick = LL(0x7fffffffffffffff); diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 4661375ba..ac734e5ac 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -26,37 +26,43 @@ # # Authors: Nathan Binkert -from MemObject import MemObject +import sys + +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env + from Bus import Bus from InstTracer import InstTracer from ExeTracer import ExeTracer -import sys +from MemObject import MemObject default_tracer = ExeTracer() -if build_env['TARGET_ISA'] == 'alpha': +if buildEnv['TARGET_ISA'] == 'alpha': from AlphaTLB import AlphaDTB, AlphaITB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from AlphaInterrupts import AlphaInterrupts -elif build_env['TARGET_ISA'] == 'sparc': +elif buildEnv['TARGET_ISA'] == 'sparc': from SparcTLB import SparcTLB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from SparcInterrupts import SparcInterrupts -elif build_env['TARGET_ISA'] == 'x86': +elif buildEnv['TARGET_ISA'] == 'x86': from X86TLB import X86TLB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from X86LocalApic import X86LocalApic -elif build_env['TARGET_ISA'] == 'mips': +elif buildEnv['TARGET_ISA'] == 'mips': from MipsTLB import MipsTLB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from MipsInterrupts import MipsInterrupts -elif build_env['TARGET_ISA'] == 'arm': +elif buildEnv['TARGET_ISA'] == 'arm': from ArmTLB import ArmTLB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from ArmInterrupts import ArmInterrupts +elif buildEnv['TARGET_ISA'] == 'power': + from PowerTLB import PowerTLB + if buildEnv['FULL_SYSTEM']: + from PowerInterrupts import PowerInterrupts class BaseCPU(MemObject): type = 'BaseCPU' @@ -76,47 +82,54 @@ class BaseCPU(MemObject): do_statistics_insts = Param.Bool(True, "enable statistics pseudo instructions") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: profile = Param.Latency('0ns', "trace the kernel stack") do_quiesce = Param.Bool(True, "enable quiesce instructions") else: workload = VectorParam.Process("processes to run") - if build_env['TARGET_ISA'] == 'sparc': + if buildEnv['TARGET_ISA'] == 'sparc': dtb = Param.SparcTLB(SparcTLB(), "Data TLB") itb = Param.SparcTLB(SparcTLB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: interrupts = Param.SparcInterrupts( SparcInterrupts(), "Interrupt Controller") - elif build_env['TARGET_ISA'] == 'alpha': + elif buildEnv['TARGET_ISA'] == 'alpha': dtb = Param.AlphaTLB(AlphaDTB(), "Data TLB") itb = Param.AlphaTLB(AlphaITB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: interrupts = Param.AlphaInterrupts( AlphaInterrupts(), "Interrupt Controller") - elif build_env['TARGET_ISA'] == 'x86': + elif buildEnv['TARGET_ISA'] == 'x86': dtb = Param.X86TLB(X86TLB(), "Data TLB") itb = Param.X86TLB(X86TLB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: _localApic = X86LocalApic(pio_addr=0x2000000000000000) interrupts = \ Param.X86LocalApic(_localApic, "Interrupt Controller") - elif build_env['TARGET_ISA'] == 'mips': + elif buildEnv['TARGET_ISA'] == 'mips': dtb = Param.MipsTLB(MipsTLB(), "Data TLB") itb = Param.MipsTLB(MipsTLB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: interrupts = Param.MipsInterrupts( MipsInterrupts(), "Interrupt Controller") - elif build_env['TARGET_ISA'] == 'arm': + elif buildEnv['TARGET_ISA'] == 'arm': UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?") dtb = Param.ArmTLB(ArmTLB(), "Data TLB") itb = Param.ArmTLB(ArmTLB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: interrupts = Param.ArmInterrupts( ArmInterrupts(), "Interrupt Controller") + elif buildEnv['TARGET_ISA'] == 'power': + UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?") + dtb = Param.PowerTLB(PowerTLB(), "Data TLB") + itb = Param.PowerTLB(PowerTLB(), "Instruction TLB") + if buildEnv['FULL_SYSTEM']: + interrupts = Param.PowerInterrupts( + PowerInterrupts(), "Interrupt Controller") else: print "Don't know what TLB to use for ISA %s" % \ - build_env['TARGET_ISA'] + buildEnv['TARGET_ISA'] sys.exit(1) max_insts_all_threads = Param.Counter(0, @@ -139,7 +152,7 @@ class BaseCPU(MemObject): tracer = Param.InstTracer(default_tracer, "Instruction tracer") _mem_ports = [] - if build_env['TARGET_ISA'] == 'x86' and build_env['FULL_SYSTEM']: + if buildEnv['TARGET_ISA'] == 'x86' and buildEnv['FULL_SYSTEM']: _mem_ports = ["itb.walker.port", "dtb.walker.port", "interrupts.pio", @@ -157,7 +170,7 @@ class BaseCPU(MemObject): self.icache_port = ic.cpu_side self.dcache_port = dc.cpu_side self._mem_ports = ['icache.mem_side', 'dcache.mem_side'] - if build_env['TARGET_ISA'] == 'x86' and build_env['FULL_SYSTEM']: + if buildEnv['TARGET_ISA'] == 'x86' and buildEnv['FULL_SYSTEM']: self._mem_ports += ["itb.walker_port", "dtb.walker_port"] def addTwoLevelCacheHierarchy(self, ic, dc, l2c): @@ -168,7 +181,7 @@ class BaseCPU(MemObject): self.l2cache.cpu_side = self.toL2Bus.port self._mem_ports = ['l2cache.mem_side'] - if build_env['TARGET_ISA'] == 'mips': + if buildEnv['TARGET_ISA'] == 'mips': CP0_IntCtl_IPTI = Param.Unsigned(0,"No Description") CP0_IntCtl_IPPCI = Param.Unsigned(0,"No Description") CP0_SrsCtl_HSS = Param.Unsigned(0,"No Description") diff --git a/src/cpu/CheckerCPU.py b/src/cpu/CheckerCPU.py index bff9af62d..132254413 100644 --- a/src/cpu/CheckerCPU.py +++ b/src/cpu/CheckerCPU.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU class CheckerCPU(BaseCPU): diff --git a/src/cpu/SConscript b/src/cpu/SConscript index ea79b622c..b89a589c6 100644 --- a/src/cpu/SConscript +++ b/src/cpu/SConscript @@ -160,6 +160,7 @@ TraceFlag('DynInst') TraceFlag('ExecEnable') TraceFlag('ExecCPSeq') TraceFlag('ExecEffAddr') +TraceFlag('ExecFaulting', 'Trace faulting instructions') TraceFlag('ExecFetchSeq') TraceFlag('ExecOpClass') TraceFlag('ExecRegDelta') @@ -176,6 +177,6 @@ TraceFlag('PCEvent') TraceFlag('Quiesce') CompoundFlag('Exec', [ 'ExecEnable', 'ExecTicks', 'ExecOpClass', 'ExecThread', - 'ExecEffAddr', 'ExecResult', 'ExecSymbol', 'ExecMicro' ]) + 'ExecEffAddr', 'ExecResult', 'ExecSymbol', 'ExecMicro', 'ExecFaulting' ]) CompoundFlag('ExecNoTicks', [ 'ExecEnable', 'ExecOpClass', 'ExecThread', - 'ExecEffAddr', 'ExecResult', 'ExecMicro' ]) + 'ExecEffAddr', 'ExecResult', 'ExecMicro', 'ExecFaulting' ]) diff --git a/src/cpu/base.cc b/src/cpu/base.cc index e4cb79344..556e7ec6f 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -151,7 +151,7 @@ BaseCPU::BaseCPU(Params *p) *counter = numThreads; for (ThreadID tid = 0; tid < numThreads; ++tid) { Event *event = new CountedExitEvent(cause, *counter); - comInstEventQueue[tid]->schedule(event, p->max_insts_any_thread); + comInstEventQueue[tid]->schedule(event, p->max_insts_all_threads); } } diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 441d9b5dd..bfeec0870 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -38,6 +38,7 @@ #include "arch/microcode_rom.hh" #include "base/statistics.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "sim/eventq.hh" #include "sim/insttracer.hh" #include "mem/mem_object.hh" diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index f4ff88209..31206c81e 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -39,6 +39,7 @@ #include "base/fast_alloc.hh" #include "base/trace.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/o3/comm.hh" #include "cpu/exetrace.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh index 4ee7d2f2c..70c91ceda 100644 --- a/src/cpu/base_dyn_inst_impl.hh +++ b/src/cpu/base_dyn_inst_impl.hh @@ -35,12 +35,11 @@ #include "base/cprintf.hh" #include "base/trace.hh" - -#include "sim/faults.hh" +#include "config/the_isa.hh" +#include "cpu/base_dyn_inst.hh" #include "cpu/exetrace.hh" #include "mem/request.hh" - -#include "cpu/base_dyn_inst.hh" +#include "sim/faults.hh" #define NOHASH #ifndef NOHASH diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc index 7dacc58ff..16b779e06 100644 --- a/src/cpu/checker/cpu.cc +++ b/src/cpu/checker/cpu.cc @@ -326,7 +326,7 @@ CheckerCPU::checkFlags(Request *req) { // Remove any dynamic flags that don't have to do with the request itself. unsigned flags = unverifiedReq->getFlags(); - unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | NO_FAULT; + unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | PREFETCH; flags = flags & (mask); if (flags == req->getFlags()) { return false; diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 26571ed68..81f494630 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -32,6 +32,7 @@ #include <string> #include "base/refcnt.hh" +#include "config/the_isa.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/checker/cpu.hh" #include "cpu/simple_thread.hh" diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index d38bd2915..ef7d4c643 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -32,6 +32,7 @@ #define __CPU_CHECKER_THREAD_CONTEXT_HH__ #include "arch/types.hh" +#include "config/the_isa.hh" #include "cpu/checker/cpu.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index ea53fb6f5..07be700bb 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -38,6 +38,7 @@ #include "cpu/exetrace.hh" #include "cpu/static_inst.hh" #include "cpu/thread_context.hh" +#include "config/the_isa.hh" #include "enums/OpClass.hh" using namespace std; diff --git a/src/cpu/inorder/InOrderCPU.py b/src/cpu/inorder/InOrderCPU.py index 9faadc68c..a0b0466a7 100644 --- a/src/cpu/inorder/InOrderCPU.py +++ b/src/cpu/inorder/InOrderCPU.py @@ -28,7 +28,6 @@ from m5.params import * from m5.proxy import * -from m5 import build_env from BaseCPU import BaseCPU class InOrderCPU(BaseCPU): diff --git a/src/cpu/inorder/SConscript b/src/cpu/inorder/SConscript index 64f1b5481..82a1028c2 100644 --- a/src/cpu/inorder/SConscript +++ b/src/cpu/inorder/SConscript @@ -79,6 +79,7 @@ if 'InOrderCPU' in env['CPU_MODELS']: Source('resources/mult_div_unit.cc') Source('resource_pool.cc') Source('reg_dep_map.cc') + Source('thread_state.cc') Source('thread_context.cc') Source('cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index a2367db63..1e3fdc40e 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -33,24 +33,34 @@ #include "arch/utility.hh" #include "config/full_system.hh" -#include "cpu/exetrace.hh" +#include "config/the_isa.hh" #include "cpu/activity.hh" -#include "cpu/simple_thread.hh" -#include "cpu/thread_context.hh" #include "cpu/base.hh" -#include "cpu/inorder/inorder_dyn_inst.hh" -#include "cpu/inorder/thread_context.hh" -#include "cpu/inorder/thread_state.hh" +#include "cpu/exetrace.hh" #include "cpu/inorder/cpu.hh" -#include "params/InOrderCPU.hh" -#include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/first_stage.hh" -#include "cpu/inorder/resources/resource_list.hh" +#include "cpu/inorder/inorder_dyn_inst.hh" +#include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/resource_pool.hh" +#include "cpu/inorder/resources/resource_list.hh" +#include "cpu/inorder/thread_context.hh" +#include "cpu/inorder/thread_state.hh" +#include "cpu/simple_thread.hh" +#include "cpu/thread_context.hh" #include "mem/translating_port.hh" +#include "params/InOrderCPU.hh" #include "sim/process.hh" #include "sim/stat_control.hh" +#if FULL_SYSTEM +#include "cpu/quiesce_event.hh" +#include "sim/system.hh" +#endif + +#if THE_ISA == ALPHA_ISA +#include "arch/alpha/osfpal.hh" +#endif + using namespace std; using namespace TheISA; using namespace ThePipeline; @@ -171,11 +181,16 @@ InOrderCPU::InOrderCPU(Params *params) timeBuffer(2 , 2), removeInstsThisCycle(false), activityRec(params->name, NumStages, 10, params->activity), +#if FULL_SYSTEM + system(params->system), + physmem(system->physmem), +#endif // FULL_SYSTEM switchCount(0), deferRegistration(false/*params->deferRegistration*/), stageTracing(params->stageTracing), numVirtProcs(1) { + ThreadID active_threads; cpu_params = params; resPool = new ResourcePool(this, params); @@ -183,13 +198,17 @@ InOrderCPU::InOrderCPU(Params *params) // Resize for Multithreading CPUs thread.resize(numThreads); - ThreadID active_threads = params->workload.size(); +#if FULL_SYSTEM + active_threads = 1; +#else + active_threads = params->workload.size(); if (active_threads > MaxThreads) { panic("Workload Size too large. Increase the 'MaxThreads'" "in your InOrder implementation or " "edit your workload size."); } +#endif // Bind the fetch & data ports from the resource pool. fetchPortIdx = resPool->getPortIdx(params->fetchMemPort); @@ -203,17 +222,23 @@ InOrderCPU::InOrderCPU(Params *params) } for (ThreadID tid = 0; tid < numThreads; ++tid) { +#if FULL_SYSTEM + // SMT is not supported in FS mode yet. + assert(numThreads == 1); + thread[tid] = new Thread(this, 0); +#else if (tid < (ThreadID)params->workload.size()) { DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n", - tid, this->thread[tid]); - this->thread[tid] = + tid, params->workload[tid]->prog_fname); + thread[tid] = new Thread(this, tid, params->workload[tid]); } else { //Allocate Empty thread so M5 can use later //when scheduling threads to CPU Process* dummy_proc = params->workload[0]; - this->thread[tid] = new Thread(this, tid, dummy_proc); + thread[tid] = new Thread(this, tid, dummy_proc); } +#endif // Setup the TC that will serve as the interface to the threads/CPU. InOrderThreadContext *tc = new InOrderThreadContext; @@ -410,7 +435,7 @@ InOrderCPU::tick() //Tick next_tick = curTick + cycles(1); //tickEvent.schedule(next_tick); mainEventQueue.schedule(&tickEvent, nextCycle(curTick + 1)); - DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", nextCycle() + curTick); + DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", nextCycle(curTick + 1)); } } @@ -447,13 +472,6 @@ InOrderCPU::init() } void -InOrderCPU::readFunctional(Addr addr, uint32_t &buffer) -{ - tcBase()->getMemPort()->readBlob(addr, (uint8_t*)&buffer, sizeof(uint32_t)); - buffer = gtoh(buffer); -} - -void InOrderCPU::reset() { for (int i = 0; i < numThreads; i++) { @@ -468,6 +486,61 @@ InOrderCPU::getPort(const std::string &if_name, int idx) return resPool->getPort(if_name, idx); } +#if FULL_SYSTEM +Fault +InOrderCPU::hwrei(ThreadID tid) +{ + panic("hwrei: Unimplemented"); + + return NoFault; +} + + +bool +InOrderCPU::simPalCheck(int palFunc, ThreadID tid) +{ + panic("simPalCheck: Unimplemented"); + + return true; +} + + +Fault +InOrderCPU::getInterrupts() +{ + // Check if there are any outstanding interrupts + return this->interrupts->getInterrupt(this->threadContexts[0]); +} + + +void +InOrderCPU::processInterrupts(Fault interrupt) +{ + // Check for interrupts here. For now can copy the code that + // exists within isa_fullsys_traits.hh. Also assume that thread 0 + // is the one that handles the interrupts. + // @todo: Possibly consolidate the interrupt checking code. + // @todo: Allow other threads to handle interrupts. + + assert(interrupt != NoFault); + this->interrupts->updateIntrInfo(this->threadContexts[0]); + + DPRINTF(InOrderCPU, "Interrupt %s being handled\n", interrupt->name()); + this->trap(interrupt, 0); +} + + +void +InOrderCPU::updateMemPorts() +{ + // Update all ThreadContext's memory ports (Functional/Virtual + // Ports) + ThreadID size = thread.size(); + for (ThreadID i = 0; i < size; ++i) + thread[i]->connectMemPorts(thread[i]->getTC()); +} +#endif + void InOrderCPU::trap(Fault fault, ThreadID tid, int delay) { @@ -1230,6 +1303,22 @@ InOrderCPU::wakeCPU() mainEventQueue.schedule(&tickEvent, curTick); } +#if FULL_SYSTEM + +void +InOrderCPU::wakeup() +{ + if (this->thread[0]->status() != ThreadContext::Suspended) + return; + + this->wakeCPU(); + + DPRINTF(Quiesce, "Suspended Processor woken\n"); + this->threadContexts[0]->activate(); +} +#endif + +#if !FULL_SYSTEM void InOrderCPU::syscall(int64_t callnum, ThreadID tid) { @@ -1251,6 +1340,7 @@ InOrderCPU::syscall(int64_t callnum, ThreadID tid) // Clear Non-Speculative Block Variable nonSpecInstActive[tid] = false; } +#endif void InOrderCPU::prefetch(DynInstPtr inst) diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index 75d77c818..3320532ba 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -40,10 +40,12 @@ #include "arch/isa_traits.hh" #include "arch/types.hh" +#include "arch/registers.hh" #include "base/statistics.hh" #include "base/timebuf.hh" #include "base/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/activity.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" @@ -297,6 +299,32 @@ class InOrderCPU : public BaseCPU /** Get a Memory Port */ Port* getPort(const std::string &if_name, int idx = 0); +#if FULL_SYSTEM + /** HW return from error interrupt. */ + Fault hwrei(ThreadID tid); + + bool simPalCheck(int palFunc, ThreadID tid); + + /** Returns the Fault for any valid interrupt. */ + Fault getInterrupts(); + + /** Processes any an interrupt fault. */ + void processInterrupts(Fault interrupt); + + /** Halts the CPU. */ + void halt() { panic("Halt not implemented!\n"); } + + /** Update the Virt and Phys ports of all ThreadContexts to + * reflect change in memory connections. */ + void updateMemPorts(); + + /** Check if this address is a valid instruction address. */ + bool validInstAddr(Addr addr) { return true; } + + /** Check if this address is a valid data address. */ + bool validDataAddr(Addr addr) { return true; } +#endif + /** trap() - sets up a trap event on the cpuTraps to handle given fault. * trapCPU() - Traps to handle given fault */ @@ -578,8 +606,6 @@ class InOrderCPU : public BaseCPU ActivityRecorder activityRec; public: - void readFunctional(Addr addr, uint32_t &buffer); - /** Number of Active Threads in the CPU */ ThreadID numActiveThreads() { return activeThreads.size(); } @@ -597,6 +623,10 @@ class InOrderCPU : public BaseCPU /** Wakes the CPU, rescheduling the CPU if it's not already active. */ void wakeCPU(); +#if FULL_SYSTEM + virtual void wakeup(); +#endif + /** Gets a free thread id. Use if thread ids change across system. */ ThreadID getFreeTid(); @@ -622,6 +652,14 @@ class InOrderCPU : public BaseCPU return total; } +#if FULL_SYSTEM + /** Pointer to the system. */ + System *system; + + /** Pointer to physical memory. */ + PhysicalMemory *physmem; +#endif + /** The global sequence number counter. */ InstSeqNum globalSeqNum[ThePipeline::MaxThreads]; diff --git a/src/cpu/inorder/inorder_cpu_builder.cc b/src/cpu/inorder/inorder_cpu_builder.cc index 5ee7b31db..a19137dd8 100644 --- a/src/cpu/inorder/inorder_cpu_builder.cc +++ b/src/cpu/inorder/inorder_cpu_builder.cc @@ -42,12 +42,17 @@ InOrderCPU * InOrderCPUParams::create() { +#if FULL_SYSTEM + // Full-system only supports a single thread for the moment. + ThreadID actual_num_threads = 1; +#else ThreadID actual_num_threads = (numThreads >= workload.size()) ? numThreads : workload.size(); if (workload.size() == 0) { fatal("Must specify at least one workload!"); } +#endif numThreads = actual_num_threads; diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index a6abb28b2..5ab839615 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -34,15 +34,14 @@ #include <string> #include <sstream> +#include "arch/faults.hh" #include "base/cprintf.hh" #include "base/trace.hh" - -#include "arch/faults.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" -#include "mem/request.hh" - -#include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/cpu.hh" +#include "cpu/inorder/inorder_dyn_inst.hh" +#include "mem/request.hh" using namespace std; using namespace TheISA; @@ -297,11 +296,39 @@ InOrderDynInst::memAccess() return initiateAcc(); } + +#if FULL_SYSTEM + +Fault +InOrderDynInst::hwrei() +{ + panic("InOrderDynInst: hwrei: unimplemented\n"); + return NoFault; +} + + +void +InOrderDynInst::trap(Fault fault) +{ + this->cpu->trap(fault, this->threadNumber); +} + + +bool +InOrderDynInst::simPalCheck(int palFunc) +{ +#if THE_ISA != ALPHA_ISA + panic("simPalCheck called, but PAL only exists in Alpha!\n"); +#endif + return this->cpu->simPalCheck(palFunc, this->threadNumber); +} +#else void InOrderDynInst::syscall(int64_t callnum) { cpu->syscall(callnum, this->threadNumber); } +#endif void InOrderDynInst::prefetch(Addr addr, unsigned flags) diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index e95a6d039..522b4e8d7 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -37,25 +37,31 @@ #include <list> #include <string> -#include "arch/isa_traits.hh" #include "arch/faults.hh" -#include "arch/types.hh" +#include "arch/isa_traits.hh" #include "arch/mt.hh" +#include "arch/types.hh" #include "base/fast_alloc.hh" #include "base/trace.hh" -#include "cpu/inorder/inorder_trace.hh" +#include "base/types.hh" #include "config/full_system.hh" -#include "cpu/thread_context.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" +#include "cpu/inorder/inorder_trace.hh" +#include "cpu/inorder/pipeline_traits.hh" +#include "cpu/inorder/resource.hh" +#include "cpu/inorder/thread_state.hh" #include "cpu/inst_seq.hh" #include "cpu/op_class.hh" #include "cpu/static_inst.hh" -#include "cpu/inorder/thread_state.hh" -#include "cpu/inorder/resource.hh" -#include "cpu/inorder/pipeline_traits.hh" +#include "cpu/thread_context.hh" #include "mem/packet.hh" #include "sim/system.hh" +#if THE_ISA == ALPHA_ISA +#include "arch/alpha/ev5.hh" +#endif + /** * @file * Defines a dynamic instruction context for a inorder CPU model. @@ -64,6 +70,7 @@ // Forward declaration. class StaticInstPtr; class ResourceRequest; +class Packet; class InOrderDynInst : public FastAlloc, public RefCounted { @@ -486,7 +493,16 @@ class InOrderDynInst : public FastAlloc, public RefCounted void setCurResSlot(unsigned slot_num) { curResSlot = slot_num; } /** Calls a syscall. */ +#if FULL_SYSTEM + /** Calls hardware return from error interrupt. */ + Fault hwrei(); + /** Traps to handle specified fault. */ + void trap(Fault fault); + bool simPalCheck(int palFunc); +#else + /** Calls a syscall. */ void syscall(int64_t callnum); +#endif void prefetch(Addr addr, unsigned flags); void writeHint(Addr addr, int size, unsigned flags); Fault copySrcTranslate(Addr src); diff --git a/src/cpu/inorder/inorder_trace.cc b/src/cpu/inorder/inorder_trace.cc index f12a1b7a9..90c94a4f5 100644 --- a/src/cpu/inorder/inorder_trace.cc +++ b/src/cpu/inorder/inorder_trace.cc @@ -31,6 +31,7 @@ #include <iomanip> +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/inorder/inorder_trace.hh" #include "cpu/static_inst.hh" diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index 46b1cbad0..dc0378bf3 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -30,6 +30,7 @@ */ #include "base/str.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_stage.hh" #include "cpu/inorder/resource_pool.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/reg_dep_map.cc b/src/cpu/inorder/reg_dep_map.cc index a405b1fb9..51782a588 100644 --- a/src/cpu/inorder/reg_dep_map.cc +++ b/src/cpu/inorder/reg_dep_map.cc @@ -30,6 +30,7 @@ */ #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/reg_dep_map.hh" #include "cpu/inorder/inorder_dyn_inst.hh" diff --git a/src/cpu/inorder/reg_dep_map.hh b/src/cpu/inorder/reg_dep_map.hh index ba2a8c8a3..b78e211bb 100644 --- a/src/cpu/inorder/reg_dep_map.hh +++ b/src/cpu/inorder/reg_dep_map.hh @@ -36,6 +36,7 @@ #include <vector> #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" class InOrderCPU; diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh index 7935e5517..605b7f690 100644 --- a/src/cpu/inorder/resource.hh +++ b/src/cpu/inorder/resource.hh @@ -36,6 +36,7 @@ #include <list> #include <string> +#include "base/types.hh" #include "cpu/inst_seq.hh" #include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/pipeline_traits.hh" diff --git a/src/cpu/inorder/resources/bpred_unit.cc b/src/cpu/inorder/resources/bpred_unit.cc index 2ed8586aa..0e8526fa1 100644 --- a/src/cpu/inorder/resources/bpred_unit.cc +++ b/src/cpu/inorder/resources/bpred_unit.cc @@ -33,6 +33,7 @@ #include "base/trace.hh" #include "base/traceflags.hh" +#include "config/the_isa.hh" #include "cpu/inorder/resources/bpred_unit.hh" using namespace std; diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc index 905de0794..ecac5fff0 100644 --- a/src/cpu/inorder/resources/branch_predictor.cc +++ b/src/cpu/inorder/resources/branch_predictor.cc @@ -29,6 +29,7 @@ * */ +#include "config/the_isa.hh" #include "cpu/inorder/resources/branch_predictor.hh" using namespace std; diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 5677810f6..eb66e10f8 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -31,10 +31,12 @@ #include <vector> #include <list> + #include "arch/isa_traits.hh" #include "arch/locked_mem.hh" #include "arch/utility.hh" #include "arch/predecoder.hh" +#include "config/the_isa.hh" #include "cpu/inorder/resources/cache_unit.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh index 8946ad5d3..c467e9771 100644 --- a/src/cpu/inorder/resources/cache_unit.hh +++ b/src/cpu/inorder/resources/cache_unit.hh @@ -36,17 +36,17 @@ #include <list> #include <string> -#include "arch/tlb.hh" #include "arch/predecoder.hh" -#include "cpu/inorder/resource.hh" +#include "arch/tlb.hh" +#include "config/the_isa.hh" #include "cpu/inorder/inorder_dyn_inst.hh" +#include "cpu/inorder/pipeline_traits.hh" +#include "cpu/inorder/resource.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" #include "mem/port.hh" -#include "cpu/inorder/pipeline_traits.hh" -#include "sim/sim_object.hh" - #include "params/InOrderCPU.hh" +#include "sim/sim_object.hh" class CacheRequest; typedef CacheRequest* CacheReqPtr; diff --git a/src/cpu/inorder/resources/decode_unit.cc b/src/cpu/inorder/resources/decode_unit.cc index 033c318f2..33f5aba1a 100644 --- a/src/cpu/inorder/resources/decode_unit.cc +++ b/src/cpu/inorder/resources/decode_unit.cc @@ -29,6 +29,7 @@ * */ +#include "config/the_isa.hh" #include "cpu/inorder/resources/decode_unit.hh" using namespace TheISA; diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index bc809b040..1d0b92075 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -29,6 +29,7 @@ * */ +#include "config/the_isa.hh" #include "cpu/inorder/resources/fetch_seq_unit.hh" #include "cpu/inorder/resource_pool.hh" diff --git a/src/cpu/inorder/resources/fetch_seq_unit.hh b/src/cpu/inorder/resources/fetch_seq_unit.hh index 3e18d47cb..a4495564b 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.hh +++ b/src/cpu/inorder/resources/fetch_seq_unit.hh @@ -36,6 +36,7 @@ #include <list> #include <string> +#include "config/the_isa.hh" #include "cpu/inorder/resource.hh" #include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/pipeline_traits.hh" diff --git a/src/cpu/inorder/resources/inst_buffer.cc b/src/cpu/inorder/resources/inst_buffer.cc index 21df1d053..bb308b0ea 100644 --- a/src/cpu/inorder/resources/inst_buffer.cc +++ b/src/cpu/inorder/resources/inst_buffer.cc @@ -31,7 +31,9 @@ #include <vector> #include <list> + #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/resources/inst_buffer.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/resources/inst_buffer_new.cc b/src/cpu/inorder/resources/inst_buffer_new.cc index cc534ef3e..2e5a9666a 100644 --- a/src/cpu/inorder/resources/inst_buffer_new.cc +++ b/src/cpu/inorder/resources/inst_buffer_new.cc @@ -31,7 +31,9 @@ #include <vector> #include <list> + #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/resources/inst_buffer.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc index 7592c0260..e7bd6750f 100644 --- a/src/cpu/inorder/resources/mult_div_unit.cc +++ b/src/cpu/inorder/resources/mult_div_unit.cc @@ -91,7 +91,32 @@ MultDivUnit::freeSlot(int slot_idx) Resource::freeSlot(slot_idx); } - +//@TODO: Should we push this behavior into base-class to generically +// accomodate all multicyle resources? +void +MultDivUnit::requestAgain(DynInstPtr inst, bool &service_request) +{ + ResReqPtr mult_div_req = findRequest(inst); + assert(mult_div_req); + + service_request = true; + + // Check to see if this instruction is requesting the same command + // or a different one + if (mult_div_req->cmd != inst->resSched.top()->cmd) { + // If different, then update command in the request + mult_div_req->cmd = inst->resSched.top()->cmd; + DPRINTF(InOrderMDU, + "[tid:%i]: [sn:%i]: Updating the command for this instruction\n", + inst->readTid(), inst->seqNum); + } else { + // If same command, just check to see if memory access was completed + // but dont try to re-execute + DPRINTF(InOrderMDU, + "[tid:%i]: [sn:%i]: requesting this resource again\n", + inst->readTid(), inst->seqNum); + } +} int MultDivUnit::getSlot(DynInstPtr inst) { @@ -232,8 +257,13 @@ MultDivUnit::execute(int slot_num) // counting down the time { DPRINTF(InOrderMDU, "End MDU called ...\n"); - if (mult_div_req->getInst()->isExecuted()) + if (mult_div_req->getInst()->isExecuted()) { + DPRINTF(InOrderMDU, "Mult/Div finished.\n"); mult_div_req->done(); + } else { + mult_div_req->setCompleted(false); + } + } break; diff --git a/src/cpu/inorder/resources/mult_div_unit.hh b/src/cpu/inorder/resources/mult_div_unit.hh index 76180714c..d3dd0260d 100644 --- a/src/cpu/inorder/resources/mult_div_unit.hh +++ b/src/cpu/inorder/resources/mult_div_unit.hh @@ -82,6 +82,8 @@ class MultDivUnit : public Resource { /** Register extra resource stats */ virtual void regStats(); + void requestAgain(DynInstPtr inst, bool &try_request); + protected: /** Latency & Repeat Rate for Multiply Insts */ unsigned multRepeatRate; diff --git a/src/cpu/inorder/resources/tlb_unit.cc b/src/cpu/inorder/resources/tlb_unit.cc index 95bade36a..0410d6b24 100644 --- a/src/cpu/inorder/resources/tlb_unit.cc +++ b/src/cpu/inorder/resources/tlb_unit.cc @@ -31,7 +31,9 @@ #include <vector> #include <list> + #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/first_stage.hh" #include "cpu/inorder/resources/tlb_unit.hh" diff --git a/src/cpu/inorder/resources/tlb_unit.hh b/src/cpu/inorder/resources/tlb_unit.hh index 1c08bd822..5c62c7751 100644 --- a/src/cpu/inorder/resources/tlb_unit.hh +++ b/src/cpu/inorder/resources/tlb_unit.hh @@ -36,6 +36,7 @@ #include <list> #include <string> +#include "config/the_isa.hh" #include "cpu/inorder/resources/inst_buffer.hh" #include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/pipeline_traits.hh" diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc index 2f1652c08..36392d054 100644 --- a/src/cpu/inorder/resources/use_def.cc +++ b/src/cpu/inorder/resources/use_def.cc @@ -31,7 +31,9 @@ #include <vector> #include <list> + #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/resources/use_def.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/thread_context.cc b/src/cpu/inorder/thread_context.cc index fe1a0faa1..41d16b633 100644 --- a/src/cpu/inorder/thread_context.cc +++ b/src/cpu/inorder/thread_context.cc @@ -30,23 +30,77 @@ */ #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/inorder/thread_context.hh" using namespace TheISA; +#if FULL_SYSTEM + +VirtualPort * +InOrderThreadContext::getVirtPort() +{ + return thread->getVirtPort(); +} + + +void +InOrderThreadContext::dumpFuncProfile() +{ + thread->dumpFuncProfile(); +} + + +Tick +InOrderThreadContext::readLastActivate() +{ + return thread->lastActivate; +} + + +Tick +InOrderThreadContext::readLastSuspend() +{ + return thread->lastSuspend; +} + + +void +InOrderThreadContext::profileClear() +{ + thread->profileClear(); +} + + +void +InOrderThreadContext::profileSample() +{ + thread->profileSample(); +} +#endif + void InOrderThreadContext::takeOverFrom(ThreadContext *old_context) { // some things should already be set up + assert(getSystemPtr() == old_context->getSystemPtr()); +#if !FULL_SYSTEM assert(getProcessPtr() == old_context->getProcessPtr()); +#endif + + // copy over functional state setStatus(old_context->status()); copyArchRegs(old_context); +#if !FULL_SYSTEM thread->funcExeInst = old_context->readFuncExeInst(); +#endif + old_context->setStatus(ThreadContext::Halted); + thread->inSyscall = false; thread->trapPending = false; } @@ -97,8 +151,8 @@ void InOrderThreadContext::regStats(const std::string &name) { #if FULL_SYSTEM - thread->kernelStats = new Kernel::Statistics(cpu->system); - thread->kernelStats->regStats(name + ".kern"); + //thread->kernelStats = new Kernel::Statistics(cpu->system); + //thread->kernelStats->regStats(name + ".kern"); #endif ; } @@ -107,22 +161,14 @@ InOrderThreadContext::regStats(const std::string &name) void InOrderThreadContext::serialize(std::ostream &os) { -#if FULL_SYSTEM - if (thread->kernelStats) - thread->kernelStats->serialize(os); -#endif - ; + panic("serialize unimplemented"); } void InOrderThreadContext::unserialize(Checkpoint *cp, const std::string §ion) { -#if FULL_SYSTEM - if (thread->kernelStats) - thread->kernelStats->unserialize(cp, section); -#endif - ; + panic("unserialize unimplemented"); } TheISA::MachInst diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh index 327f8ac71..820f3077f 100644 --- a/src/cpu/inorder/thread_context.hh +++ b/src/cpu/inorder/thread_context.hh @@ -32,6 +32,7 @@ #ifndef __CPU_INORDER_THREAD_CONTEXT_HH__ #define __CPU_INORDER_THREAD_CONTEXT_HH__ +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/thread_context.hh" #include "cpu/inorder/thread_state.hh" @@ -101,10 +102,48 @@ class InOrderThreadContext : public ThreadContext virtual void setNextMicroPC(uint64_t val) { }; +#if FULL_SYSTEM + /** Returns a pointer to physical memory. */ + virtual PhysicalMemory *getPhysMemPtr() + { assert(0); return 0; /*return cpu->physmem;*/ } + + /** Returns a pointer to this thread's kernel statistics. */ + virtual TheISA::Kernel::Statistics *getKernelStats() + { return thread->kernelStats; } + + virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); } + + virtual VirtualPort *getVirtPort(); + + virtual void connectMemPorts(ThreadContext *tc) { thread->connectMemPorts(tc); } + + /** Dumps the function profiling information. + * @todo: Implement. + */ + virtual void dumpFuncProfile(); + + /** Reads the last tick that this thread was activated on. */ + virtual Tick readLastActivate(); + /** Reads the last tick that this thread was suspended on. */ + virtual Tick readLastSuspend(); + + /** Clears the function profiling information. */ + virtual void profileClear(); + + /** Samples the function profiling information. */ + virtual void profileSample(); + + /** Returns pointer to the quiesce event. */ + virtual EndQuiesceEvent *getQuiesceEvent() + { + return this->thread->quiesceEvent; + } +#else virtual TranslatingPort *getMemPort() { return thread->getMemPort(); } /** Returns a pointer to this thread's process. */ virtual Process *getProcessPtr() { return thread->getProcessPtr(); } +#endif /** Returns this thread's status. */ virtual Status status() const { return thread->status(); } @@ -232,9 +271,11 @@ class InOrderThreadContext : public ThreadContext * misspeculating, this is set as false. */ virtual bool misspeculating() { return false; } +#if !FULL_SYSTEM /** Executes a syscall in SE mode. */ virtual void syscall(int64_t callnum) { return cpu->syscall(callnum, thread->readTid()); } +#endif /** Reads the funcExeInst counter. */ virtual Counter readFuncExeInst() { return thread->funcExeInst; } diff --git a/src/mem/slicc/generator/fileio.hh b/src/cpu/inorder/thread_state.cc index 81b7306bc..b3a54efb1 100644 --- a/src/mem/slicc/generator/fileio.hh +++ b/src/cpu/inorder/thread_state.cc @@ -1,6 +1,5 @@ - /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2007 MIPS Technologies, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,22 +24,24 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * fileio.hh - * - * Description: * - * $Id: fileio.hh,v 3.2 2003/02/24 20:54:25 xu Exp $ + * Authors: Korey Sewell * - * */ + */ -#ifndef FILEIO_H -#define FILEIO_H +#include "arch/isa_traits.hh" +#include "cpu/exetrace.hh" +#include "cpu/inorder/thread_state.hh" +#include "cpu/inorder/cpu.hh" -#include "mem/slicc/slicc_global.hh" +using namespace TheISA; -void conditionally_write_file(string filename, ostringstream& sstr); +#if FULL_SYSTEM +void +InOrderThreadState::dumpFuncProfile() +{ + std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); + profile->dump(tc, *os); +} +#endif -#endif //FILEIO_H diff --git a/src/cpu/inorder/thread_state.hh b/src/cpu/inorder/thread_state.hh index 9b3b39fcb..422df30aa 100644 --- a/src/cpu/inorder/thread_state.hh +++ b/src/cpu/inorder/thread_state.hh @@ -33,13 +33,23 @@ #include "arch/faults.hh" #include "arch/isa_traits.hh" +#include "base/callback.hh" +#include "base/output.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" +#include "sim/sim_exit.hh" class Event; +class InOrderCPU; + +#if FULL_SYSTEM +class EndQuiesceEvent; +class FunctionProfile; +class ProfileNode; +#else class FunctionalMemory; class Process; -class InOrderCPU; +#endif /** * Class that has various thread state, such as the status, the @@ -66,16 +76,28 @@ class InOrderThreadState : public ThreadState { */ bool trapPending; - +#if FULL_SYSTEM + InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num) + : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), _thread_num), + cpu(_cpu), inSyscall(0), trapPending(0) + { } +#else InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num, Process *_process) - : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), 0/*_thread_num*/, + : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), _thread_num, _process), cpu(_cpu), inSyscall(0), trapPending(0) { } +#endif +#if !FULL_SYSTEM /** Handles the syscall. */ void syscall(int64_t callnum) { process->syscall(callnum, tc); } +#endif + +#if FULL_SYSTEM + void dumpFuncProfile(); +#endif /** Pointer to the ThreadContext of this thread. */ ThreadContext *tc; @@ -83,7 +105,7 @@ class InOrderThreadState : public ThreadState { /** Returns a pointer to the TC of this thread. */ ThreadContext *getTC() { return tc; } - int readTid() { return 0; } + int readTid() { return threadId(); } /** Pointer to the last graduated instruction in the thread */ //DynInstPtr lastGradInst; diff --git a/src/cpu/inst_seq.hh b/src/cpu/inst_seq.hh index 21e04ed25..b5feaf584 100644 --- a/src/cpu/inst_seq.hh +++ b/src/cpu/inst_seq.hh @@ -32,6 +32,8 @@ #ifndef __STD_TYPES_HH__ #define __STD_TYPES_HH__ +#include "base/types.hh" + // inst sequence type, used to order instructions in the ready list, // if this rolls over the ready list order temporarily will get messed // up, but execution will continue and complete correctly diff --git a/src/cpu/inteltrace.cc b/src/cpu/inteltrace.cc index 145075dc1..ec51b80e7 100644 --- a/src/cpu/inteltrace.cc +++ b/src/cpu/inteltrace.cc @@ -33,6 +33,7 @@ #include <iomanip> +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/inteltrace.hh" #include "cpu/static_inst.hh" diff --git a/src/cpu/legiontrace.cc b/src/cpu/legiontrace.cc index 5face4391..1390d0807 100644 --- a/src/cpu/legiontrace.cc +++ b/src/cpu/legiontrace.cc @@ -31,7 +31,7 @@ * Steve Raasch */ -#include "arch/isa_specific.hh" +#include "config/the_isa.hh" #if THE_ISA != SPARC_ISA #error Legion tracing only works with SPARC simulations! #endif @@ -41,10 +41,12 @@ #error Legion tracing only works in full system! #endif -#include <iomanip> #include <sys/ipc.h> #include <sys/shm.h> +#include <cstdio> +#include <iomanip> + #include "arch/sparc/predecoder.hh" #include "arch/sparc/registers.hh" #include "arch/sparc/utility.hh" diff --git a/src/cpu/memtest/MemTest.py b/src/cpu/memtest/MemTest.py index 629fd4877..8e1b3a8d0 100644 --- a/src/cpu/memtest/MemTest.py +++ b/src/cpu/memtest/MemTest.py @@ -29,7 +29,6 @@ from MemObject import MemObject from m5.params import * from m5.proxy import * -from m5 import build_env class MemTest(MemObject): type = 'MemTest' diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py index 56e537ad2..3f2210e44 100644 --- a/src/cpu/o3/O3CPU.py +++ b/src/cpu/o3/O3CPU.py @@ -26,21 +26,21 @@ # # Authors: Kevin Lim +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env from BaseCPU import BaseCPU from FUPool import * -if build_env['USE_CHECKER']: +if buildEnv['USE_CHECKER']: from O3Checker import O3Checker class DerivO3CPU(BaseCPU): type = 'DerivO3CPU' activity = Param.Unsigned(0, "Initial count") - if build_env['USE_CHECKER']: - if not build_env['FULL_SYSTEM']: + if buildEnv['USE_CHECKER']: + if not buildEnv['FULL_SYSTEM']: checker = Param.BaseCPU(O3Checker(workload=Parent.workload, exitOnError=False, updateOnError=True, diff --git a/src/cpu/o3/O3Checker.py b/src/cpu/o3/O3Checker.py index edc6dc9b6..d0c4ce537 100644 --- a/src/cpu/o3/O3Checker.py +++ b/src/cpu/o3/O3Checker.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU class O3Checker(BaseCPU): diff --git a/src/cpu/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh index 1378ac135..ed3471761 100644 --- a/src/cpu/o3/bpred_unit_impl.hh +++ b/src/cpu/o3/bpred_unit_impl.hh @@ -28,16 +28,16 @@ * Authors: Kevin Lim */ +#include <algorithm> + #include "arch/types.hh" #include "arch/isa_traits.hh" #include "base/trace.hh" #include "base/traceflags.hh" +#include "config/the_isa.hh" #include "cpu/o3/bpred_unit.hh" - #include "params/DerivO3CPU.hh" -#include <algorithm> - template<class Impl> BPredUnit<Impl>::BPredUnit(DerivO3CPUParams *params) : _name(params->name + ".BPredUnit"), diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 7286f1b6f..cb5f23814 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -37,6 +37,7 @@ #include "base/loader/symtab.hh" #include "base/timebuf.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" #include "cpu/exetrace.hh" #include "cpu/o3/commit.hh" @@ -1075,9 +1076,11 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num) commitStatus[tid] = TrapPending; if (head_inst->traceData) { - head_inst->traceData->setFetchSeq(head_inst->seqNum); - head_inst->traceData->setCPSeq(thread[tid]->numInst); - head_inst->traceData->dump(); + if (DTRACE(ExecFaulting)) { + head_inst->traceData->setFetchSeq(head_inst->seqNum); + head_inst->traceData->setCPSeq(thread[tid]->numInst); + head_inst->traceData->dump(); + } delete head_inst->traceData; head_inst->traceData = NULL; } diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 6722941e4..2a4e0176a 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -30,8 +30,8 @@ */ #include "config/full_system.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" - #include "cpu/activity.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" @@ -200,7 +200,6 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) globalSeqNum(1), #if FULL_SYSTEM system(params->system), - physmem(system->physmem), #endif // FULL_SYSTEM drainCount(0), deferRegistration(params->defer_registration) diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 0cc8eab78..2ea918983 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -42,6 +42,7 @@ #include "base/statistics.hh" #include "base/timebuf.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" #include "cpu/activity.hh" #include "cpu/base.hh" @@ -668,9 +669,6 @@ class FullO3CPU : public BaseO3CPU #if FULL_SYSTEM /** Pointer to the system. */ System *system; - - /** Pointer to physical memory. */ - PhysicalMemory *physmem; #endif /** Event to call process() on once draining has completed. */ diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh index 86f87991c..1b76de132 100644 --- a/src/cpu/o3/decode_impl.hh +++ b/src/cpu/o3/decode_impl.hh @@ -28,6 +28,7 @@ * Authors: Kevin Lim */ +#include "config/the_isa.hh" #include "cpu/o3/decode.hh" #include "params/DerivO3CPU.hh" diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index 3ef42e91f..e1279f82b 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -32,6 +32,7 @@ #define __CPU_O3_DYN_INST_HH__ #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/inst_seq.hh" #include "cpu/o3/cpu.hh" diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 9cbc50899..425c34428 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -36,6 +36,7 @@ #include "arch/predecoder.hh" #include "base/statistics.hh" #include "base/timebuf.hh" +#include "config/the_isa.hh" #include "cpu/pc_event.hh" #include "mem/packet.hh" #include "mem/port.hh" diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 3781113bd..e6815ef8a 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -35,6 +35,7 @@ #include "arch/isa_traits.hh" #include "arch/utility.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" #include "cpu/checker/cpu.hh" #include "cpu/exetrace.hh" @@ -1263,6 +1264,8 @@ DefaultFetch<Impl>::fetch(bool &status_change) toDecode->insts[numInst] = instruction; toDecode->size++; + wroteToTimeBuffer = true; + DPRINTF(Fetch, "[tid:%i]: Blocked, need to handle the trap.\n",tid); fetchStatus[tid] = TrapPending; diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh index e28c4910e..96289f641 100644 --- a/src/cpu/o3/free_list.hh +++ b/src/cpu/o3/free_list.hh @@ -38,6 +38,7 @@ #include "base/misc.hh" #include "base/trace.hh" #include "base/traceflags.hh" +#include "config/the_isa.hh" #include "cpu/o3/comm.hh" /** diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index ba29df196..751a26afd 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -35,6 +35,7 @@ #include <queue> #include "base/timebuf.hh" +#include "config/the_isa.hh" #include "cpu/o3/fu_pool.hh" #include "cpu/o3/iew.hh" #include "params/DerivO3CPU.hh" diff --git a/src/cpu/o3/impl.hh b/src/cpu/o3/impl.hh index 4b29b4daa..ffccd4a84 100644 --- a/src/cpu/o3/impl.hh +++ b/src/cpu/o3/impl.hh @@ -32,7 +32,7 @@ #define __CPU_O3_IMPL_HH__ #include "arch/isa_traits.hh" - +#include "config/the_isa.hh" #include "cpu/o3/cpu_policy.hh" diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index a917caef3..6ff36d929 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -40,6 +40,7 @@ #include "arch/faults.hh" #include "arch/locked_mem.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "base/fast_alloc.hh" #include "base/hashmap.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index edc8c9b3f..9ee1de45a 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -30,8 +30,8 @@ */ #include "arch/locked_mem.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" - #include "cpu/o3/lsq.hh" #include "cpu/o3/lsq_unit.hh" #include "base/str.hh" diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index d6beecdc5..e252fa362 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -32,18 +32,19 @@ #ifndef __CPU_O3_REGFILE_HH__ #define __CPU_O3_REGFILE_HH__ +#include <vector> + #include "arch/isa_traits.hh" #include "arch/types.hh" #include "base/trace.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/o3/comm.hh" #if FULL_SYSTEM #include "arch/kernel_stats.hh" #endif -#include <vector> - /** * Simple physical register file class. * Right now this is specific to Alpha until we decide if/how to make things diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index 734b63105..8c21dda0a 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -35,6 +35,7 @@ #include "base/statistics.hh" #include "base/timebuf.hh" +#include "config/the_isa.hh" class DerivO3CPUParams; diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index e4cc2674b..ce206435c 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -34,6 +34,7 @@ #include "arch/isa_traits.hh" #include "arch/registers.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/o3/rename.hh" #include "params/DerivO3CPU.hh" diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh index 896c66f3e..51d8db4d8 100644 --- a/src/cpu/o3/rename_map.hh +++ b/src/cpu/o3/rename_map.hh @@ -39,8 +39,9 @@ #include <utility> #include <vector> -#include "cpu/o3/free_list.hh" #include "arch/types.hh" +#include "config/the_isa.hh" +#include "cpu/o3/free_list.hh" class SimpleRenameMap { diff --git a/src/cpu/o3/rob.hh b/src/cpu/o3/rob.hh index 657bc8d06..bdea07d1a 100644 --- a/src/cpu/o3/rob.hh +++ b/src/cpu/o3/rob.hh @@ -36,6 +36,8 @@ #include <utility> #include <vector> +#include "config/the_isa.hh" + /** * ROB class. The ROB is largely what drives squashing. */ diff --git a/src/cpu/o3/scoreboard.cc b/src/cpu/o3/scoreboard.cc index e7f8b7949..ae1e13717 100644 --- a/src/cpu/o3/scoreboard.cc +++ b/src/cpu/o3/scoreboard.cc @@ -29,7 +29,7 @@ * Kevin Lim */ -#include "arch/isa_specific.hh" +#include "config/the_isa.hh" #include "cpu/o3/scoreboard.hh" Scoreboard::Scoreboard(unsigned activeThreads, diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index ed5c6ac20..78b266014 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -31,6 +31,7 @@ #ifndef __CPU_O3_THREAD_CONTEXT_HH__ #define __CPU_O3_THREAD_CONTEXT_HH__ +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/o3/isa_specific.hh" @@ -90,9 +91,6 @@ class O3ThreadContext : public ThreadContext virtual System *getSystemPtr() { return cpu->system; } #if FULL_SYSTEM - /** Returns a pointer to physical memory. */ - virtual PhysicalMemory *getPhysMemPtr() { return cpu->physmem; } - /** Returns a pointer to this thread's kernel statistics. */ virtual TheISA::Kernel::Statistics *getKernelStats() { return thread->kernelStats; } diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index e631c9244..940d460ce 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -30,6 +30,7 @@ */ #include "arch/registers.hh" +#include "config/the_isa.hh" #include "cpu/o3/thread_context.hh" #include "cpu/quiesce_event.hh" diff --git a/src/cpu/ozone/OzoneCPU.py b/src/cpu/ozone/OzoneCPU.py index 37386898d..2c7b8475f 100644 --- a/src/cpu/ozone/OzoneCPU.py +++ b/src/cpu/ozone/OzoneCPU.py @@ -26,11 +26,11 @@ # # Authors: Kevin Lim +from m5.defines import buildEnv from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU -if build_env['USE_CHECKER']: +if buildEnv['USE_CHECKER']: from OzoneChecker import OzoneChecker class DerivOzoneCPU(BaseCPU): @@ -38,7 +38,7 @@ class DerivOzoneCPU(BaseCPU): numThreads = Param.Unsigned("number of HW thread contexts") - if build_env['USE_CHECKER']: + if buildEnv['USE_CHECKER']: checker = Param.BaseCPU("Checker CPU") icache_port = Port("Instruction Port") diff --git a/src/cpu/ozone/OzoneChecker.py b/src/cpu/ozone/OzoneChecker.py index bfa39ead9..bbe46db18 100644 --- a/src/cpu/ozone/OzoneChecker.py +++ b/src/cpu/ozone/OzoneChecker.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU class OzoneChecker(BaseCPU): diff --git a/src/cpu/ozone/SimpleOzoneCPU.py b/src/cpu/ozone/SimpleOzoneCPU.py index 93603092b..d4620cd8e 100644 --- a/src/cpu/ozone/SimpleOzoneCPU.py +++ b/src/cpu/ozone/SimpleOzoneCPU.py @@ -26,8 +26,8 @@ # # Authors: Kevin Lim +from m5.defines import buildEnv from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU class SimpleOzoneCPU(BaseCPU): @@ -35,7 +35,7 @@ class SimpleOzoneCPU(BaseCPU): numThreads = Param.Unsigned("number of HW thread contexts") - if not build_env['FULL_SYSTEM']: + if not buildEnv['FULL_SYSTEM']: mem = Param.FunctionalMemory(NULL, "memory") width = Param.Unsigned("Width") diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index 5e36332af..a16986c99 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -36,6 +36,7 @@ #include "base/statistics.hh" #include "base/timebuf.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh index f86b882d1..c09dd9046 100644 --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@ -34,6 +34,7 @@ #include "arch/isa_traits.hh" // For MachInst #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh index a39f383ba..cca72ef18 100644 --- a/src/cpu/ozone/dyn_inst.hh +++ b/src/cpu/ozone/dyn_inst.hh @@ -34,6 +34,7 @@ #include "arch/isa_traits.hh" #include "arch/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/inst_seq.hh" #include "cpu/ozone/cpu.hh" // MUST include this diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh index 8519917f5..bfefb9428 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -30,6 +30,7 @@ #include "sim/faults.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/ozone/dyn_inst.hh" #if FULL_SYSTEM diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh index 38fc89e3f..3809db00d 100644 --- a/src/cpu/ozone/front_end.hh +++ b/src/cpu/ozone/front_end.hh @@ -35,6 +35,7 @@ #include "arch/utility.hh" #include "base/timebuf.hh" +#include "config/the_isa.hh" #include "cpu/inst_seq.hh" #include "cpu/o3/bpred_unit.hh" #include "cpu/ozone/rename_table.hh" diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 516823b47..884136927 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -28,12 +28,12 @@ * Authors: Kevin Lim */ -#include "config/use_checker.hh" - #include "sim/faults.hh" #include "arch/isa_traits.hh" #include "arch/utility.hh" #include "base/statistics.hh" +#include "config/the_isa.hh" +#include "config/use_checker.hh" #include "cpu/thread_context.hh" #include "cpu/exetrace.hh" #include "cpu/ozone/front_end.hh" diff --git a/src/cpu/ozone/inorder_back_end_impl.hh b/src/cpu/ozone/inorder_back_end_impl.hh index 798b628d6..2d4d225c7 100644 --- a/src/cpu/ozone/inorder_back_end_impl.hh +++ b/src/cpu/ozone/inorder_back_end_impl.hh @@ -30,6 +30,7 @@ #include "sim/faults.hh" #include "arch/types.hh" +#include "config/the_isa.hh" #include "cpu/ozone/inorder_back_end.hh" #include "cpu/ozone/thread_state.hh" diff --git a/src/cpu/ozone/lsq_unit.hh b/src/cpu/ozone/lsq_unit.hh index 47be245e5..d8e402b65 100644 --- a/src/cpu/ozone/lsq_unit.hh +++ b/src/cpu/ozone/lsq_unit.hh @@ -38,6 +38,7 @@ #include "arch/faults.hh" #include "arch/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "base/hashmap.hh" #include "cpu/inst_seq.hh" #include "mem/mem_interface.hh" diff --git a/src/cpu/ozone/lsq_unit_impl.hh b/src/cpu/ozone/lsq_unit_impl.hh index 833aa0581..dd44adf6e 100644 --- a/src/cpu/ozone/lsq_unit_impl.hh +++ b/src/cpu/ozone/lsq_unit_impl.hh @@ -30,6 +30,7 @@ #include "arch/faults.hh" #include "base/str.hh" +#include "config/the_isa.hh" #include "cpu/ozone/lsq_unit.hh" template <class Impl> diff --git a/src/cpu/ozone/lw_back_end_impl.hh b/src/cpu/ozone/lw_back_end_impl.hh index 86d4531a0..cbc386cb0 100644 --- a/src/cpu/ozone/lw_back_end_impl.hh +++ b/src/cpu/ozone/lw_back_end_impl.hh @@ -28,8 +28,8 @@ * Authors: Kevin Lim */ +#include "config/the_isa.hh" #include "config/use_checker.hh" - #include "cpu/ozone/lw_back_end.hh" #include "cpu/op_class.hh" diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh index 6e9bb77af..ee0312969 100644 --- a/src/cpu/ozone/lw_lsq.hh +++ b/src/cpu/ozone/lw_lsq.hh @@ -39,6 +39,7 @@ #include "arch/faults.hh" #include "arch/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "base/fast_alloc.hh" #include "base/hashmap.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh index 4d290a1e9..c714c5d38 100644 --- a/src/cpu/ozone/lw_lsq_impl.hh +++ b/src/cpu/ozone/lw_lsq_impl.hh @@ -28,10 +28,10 @@ * Authors: Kevin Lim */ -#include "config/use_checker.hh" - #include "arch/faults.hh" #include "base/str.hh" +#include "config/the_isa.hh" +#include "config/use_checker.hh" #include "cpu/ozone/lw_lsq.hh" #include "cpu/checker/cpu.hh" diff --git a/src/cpu/ozone/rename_table.hh b/src/cpu/ozone/rename_table.hh index 0b67d9635..9a5579158 100644 --- a/src/cpu/ozone/rename_table.hh +++ b/src/cpu/ozone/rename_table.hh @@ -32,6 +32,7 @@ #define __CPU_OZONE_RENAME_TABLE_HH__ #include "arch/isa_traits.hh" +#include "config/the_isa.hh" /** Rename table that holds the rename of each architectural register to * producing DynInst. Needs to support copying from one table to another. diff --git a/src/cpu/ozone/rename_table_impl.hh b/src/cpu/ozone/rename_table_impl.hh index 67bab7337..e8071e2b3 100644 --- a/src/cpu/ozone/rename_table_impl.hh +++ b/src/cpu/ozone/rename_table_impl.hh @@ -29,6 +29,8 @@ */ #include <cstdlib> // Not really sure what to include to get NULL + +#include "config/the_isa.hh" #include "cpu/ozone/rename_table.hh" template <class Impl> diff --git a/src/cpu/ozone/simple_params.hh b/src/cpu/ozone/simple_params.hh index 7687fdf60..b241dea73 100644 --- a/src/cpu/ozone/simple_params.hh +++ b/src/cpu/ozone/simple_params.hh @@ -31,6 +31,7 @@ #ifndef __CPU_OZONE_SIMPLE_PARAMS_HH__ #define __CPU_OZONE_SIMPLE_PARAMS_HH__ +#include "config/the_isa.hh" #include "cpu/ozone/cpu.hh" //Forward declarations diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh index 971fba886..638b9d86c 100644 --- a/src/cpu/ozone/thread_state.hh +++ b/src/cpu/ozone/thread_state.hh @@ -31,13 +31,14 @@ #ifndef __CPU_OZONE_THREAD_STATE_HH__ #define __CPU_OZONE_THREAD_STATE_HH__ -#include "sim/faults.hh" -#include "arch/types.hh" #include "arch/regfile.hh" +#include "arch/types.hh" #include "base/callback.hh" #include "base/output.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" +#include "sim/faults.hh" #include "sim/process.hh" #include "sim/sim_exit.hh" diff --git a/src/cpu/profile.hh b/src/cpu/profile.hh index 9606ed24d..dd856b5a7 100644 --- a/src/cpu/profile.hh +++ b/src/cpu/profile.hh @@ -34,6 +34,7 @@ #include <map> #include "arch/stacktrace.hh" +#include "config/the_isa.hh" #include "cpu/static_inst.hh" #include "base/types.hh" diff --git a/src/cpu/simple/AtomicSimpleCPU.py b/src/cpu/simple/AtomicSimpleCPU.py index b7174bb43..3d72f4098 100644 --- a/src/cpu/simple/AtomicSimpleCPU.py +++ b/src/cpu/simple/AtomicSimpleCPU.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseSimpleCPU import BaseSimpleCPU class AtomicSimpleCPU(BaseSimpleCPU): diff --git a/src/cpu/simple/TimingSimpleCPU.py b/src/cpu/simple/TimingSimpleCPU.py index ce6839241..6b83c41aa 100644 --- a/src/cpu/simple/TimingSimpleCPU.py +++ b/src/cpu/simple/TimingSimpleCPU.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseSimpleCPU import BaseSimpleCPU class TimingSimpleCPU(BaseSimpleCPU): diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 83da618f8..05b4ca3e2 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -32,6 +32,7 @@ #include "arch/mmaped_ipr.hh" #include "arch/utility.hh" #include "base/bigint.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/simple/atomic.hh" #include "mem/packet.hh" @@ -170,6 +171,9 @@ AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p) AtomicSimpleCPU::~AtomicSimpleCPU() { + if (tickEvent.scheduled()) { + deschedule(tickEvent); + } } void @@ -352,8 +356,14 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) recordEvent("Uncached Read"); //If there's a fault, return it - if (fault != NoFault) - return fault; + if (fault != NoFault) { + if (req->isPrefetch()) { + return NoFault; + } else { + return fault; + } + } + //If we don't need to access a second cache line, stop now. if (secondAddr <= addr) { @@ -530,7 +540,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) assert(locked); locked = false; } - return fault; + if (fault != NoFault && req->isPrefetch()) { + return NoFault; + } else { + return fault; + } } /* diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 732bb637b..0104e1b1f 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -40,6 +40,7 @@ #include "base/stats/events.hh" #include "base/trace.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" #include "cpu/profile.hh" diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 466d0d1c9..39961fb88 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -36,6 +36,7 @@ #include "arch/predecoder.hh" #include "base/statistics.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/pc_event.hh" diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 672fd9414..6b22d2fcf 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -32,6 +32,7 @@ #include "arch/mmaped_ipr.hh" #include "arch/utility.hh" #include "base/bigint.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/simple/timing.hh" #include "mem/packet.hh" @@ -272,6 +273,8 @@ TimingSimpleCPU::sendData(Fault fault, RequestPtr req, { _status = Running; if (fault != NoFault) { + if (req->isPrefetch()) + fault = NoFault; delete data; delete req; @@ -314,6 +317,10 @@ TimingSimpleCPU::sendSplitData(Fault fault1, Fault fault2, { _status = Running; if (fault1 != NoFault || fault2 != NoFault) { + if (req1->isPrefetch()) + fault1 = NoFault; + if (req2->isPrefetch()) + fault2 = NoFault; delete data; delete req1; delete req2; @@ -359,6 +366,8 @@ TimingSimpleCPU::sendSplitData(Fault fault1, Fault fault2, void TimingSimpleCPU::translationFault(Fault fault) { + // fault may be NoFault in cases where a fault is suppressed, + // for instance prefetches. numCycles += tickToCycles(curTick - previousTick); previousTick = curTick; diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 22bc283a3..ad69719ee 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -34,6 +34,7 @@ #include <string> #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" @@ -198,6 +199,11 @@ SimpleThread::serialize(ostream &os) SERIALIZE_SCALAR(nextPC); SERIALIZE_SCALAR(nextNPC); // thread_num and cpu_id are deterministic from the config + + // + // Now must serialize all the ISA dependent state + // + isa.serialize(cpu, os); } @@ -213,6 +219,11 @@ SimpleThread::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(nextPC); UNSERIALIZE_SCALAR(nextNPC); // thread_num and cpu_id are deterministic from the config + + // + // Now must unserialize all the ISA dependent state + // + isa.unserialize(cpu, cp, section); } #if FULL_SYSTEM diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 8a44eba37..2d28607b4 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -39,6 +39,7 @@ #include "arch/types.hh" #include "base/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" #include "mem/request.hh" diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index b1298e0e9..fdec09756 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -36,6 +36,7 @@ #include "arch/isa_traits.hh" #include "arch/utility.hh" +#include "config/the_isa.hh" #include "base/bitfield.hh" #include "base/hashmap.hh" #include "base/misc.hh" diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc index ab105a435..f2083ef08 100644 --- a/src/cpu/thread_context.cc +++ b/src/cpu/thread_context.cc @@ -30,6 +30,7 @@ #include "base/misc.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" void diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 9e34204ef..78ecdacf2 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -35,6 +35,7 @@ #include "arch/types.hh" #include "base/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "mem/request.hh" #include "sim/byteswap.hh" #include "sim/faults.hh" diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 5c7c0ea56..cf637aeda 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -32,6 +32,7 @@ #define __CPU_THREAD_STATE_HH__ #include "arch/types.hh" +#include "config/the_isa.hh" #include "cpu/profile.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" diff --git a/src/dev/Uart.py b/src/dev/Uart.py index 5135a064d..9254dc695 100644 --- a/src/dev/Uart.py +++ b/src/dev/Uart.py @@ -28,7 +28,6 @@ from m5.params import * from m5.proxy import * -from m5 import build_env from Device import BasicPioDevice class Uart(BasicPioDevice): diff --git a/src/dev/alpha/tsunami.cc b/src/dev/alpha/tsunami.cc index b6478fe22..b36b5977d 100644 --- a/src/dev/alpha/tsunami.cc +++ b/src/dev/alpha/tsunami.cc @@ -36,6 +36,7 @@ #include <string> #include <vector> +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "dev/alpha/tsunami_cchip.hh" #include "dev/alpha/tsunami_pchip.hh" diff --git a/src/dev/alpha/tsunami_cchip.cc b/src/dev/alpha/tsunami_cchip.cc index 52a2aea14..fd76fd93e 100644 --- a/src/dev/alpha/tsunami_cchip.cc +++ b/src/dev/alpha/tsunami_cchip.cc @@ -39,6 +39,7 @@ #include "arch/alpha/ev5.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "cpu/thread_context.hh" #include "dev/alpha/tsunami.hh" diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc index 9c88904e3..8b06f5170 100644 --- a/src/dev/alpha/tsunami_io.cc +++ b/src/dev/alpha/tsunami_io.cc @@ -42,6 +42,7 @@ #include "base/time.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/rtcreg.h" #include "dev/alpha/tsunami_cchip.hh" #include "dev/alpha/tsunami.hh" diff --git a/src/dev/alpha/tsunami_pchip.cc b/src/dev/alpha/tsunami_pchip.cc index 4df7d1150..df980cf79 100644 --- a/src/dev/alpha/tsunami_pchip.cc +++ b/src/dev/alpha/tsunami_pchip.cc @@ -38,6 +38,7 @@ #include <vector> #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/alpha/tsunami_pchip.hh" #include "dev/alpha/tsunamireg.h" #include "dev/alpha/tsunami.hh" diff --git a/src/dev/arm/SConscript b/src/dev/arm/SConscript new file mode 100644 index 000000000..dd1d73e1a --- /dev/null +++ b/src/dev/arm/SConscript @@ -0,0 +1,36 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 ARM Limited +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ali Saidi + +Import('*') + +if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'arm': + SimObject('Versatile.py') + + Source('versatile.cc') diff --git a/src/dev/arm/Versatile.py b/src/dev/arm/Versatile.py new file mode 100644 index 000000000..7f36bbcf3 --- /dev/null +++ b/src/dev/arm/Versatile.py @@ -0,0 +1,51 @@ +# Copyright (c) 2006-2007 The Regents of The University of Michigan +# Copyright (c) 2009 ARM Limited +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.params import * +from m5.proxy import * +from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr +from Platform import Platform +from Terminal import Terminal +from Uart import Uart8250 + + +class Versatile(Platform): + type = 'Versatile' + system = Param.System(Parent.any, "system") + + # Attach I/O devices that are on chip + def attachOnChipIO(self, bus): + pass + + + # Attach I/O devices to specified bus object. Can't do this + # earlier, since the bus object itself is typically defined at the + # System level. + def attachIO(self, bus): + pass diff --git a/src/dev/arm/versatile.cc b/src/dev/arm/versatile.cc new file mode 100644 index 000000000..7d571db99 --- /dev/null +++ b/src/dev/arm/versatile.cc @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** @file + * Implementation of Versatile platform. + */ + +#include <deque> +#include <string> +#include <vector> + +#include "config/the_isa.hh" +#include "cpu/intr_control.hh" +#include "dev/arm/versatile.hh" +#include "dev/terminal.hh" +#include "sim/system.hh" + +using namespace std; +using namespace TheISA; + +Versatile::Versatile(const Params *p) + : Platform(p), system(p->system) +{ + // set the back pointer from the system to myself + system->platform = this; +} + +Tick +Versatile::intrFrequency() +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +void +Versatile::postConsoleInt() +{ + warn_once("Don't know what interrupt to post for console.\n"); + //panic("Need implementation\n"); +} + +void +Versatile::clearConsoleInt() +{ + warn_once("Don't know what interrupt to clear for console.\n"); + //panic("Need implementation\n"); +} + +void +Versatile::postPciInt(int line) +{ + panic("Need implementation\n"); +} + +void +Versatile::clearPciInt(int line) +{ + panic("Need implementation\n"); +} + +Addr +Versatile::pciToDma(Addr pciAddr) const +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + + +Addr +Versatile::calcPciConfigAddr(int bus, int dev, int func) +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +Addr +Versatile::calcPciIOAddr(Addr addr) +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +Addr +Versatile::calcPciMemAddr(Addr addr) +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +Versatile * +VersatileParams::create() +{ + return new Versatile(this); +} diff --git a/src/dev/arm/versatile.hh b/src/dev/arm/versatile.hh new file mode 100644 index 000000000..edec3631c --- /dev/null +++ b/src/dev/arm/versatile.hh @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** + * @file + * Declaration of top level class for the Versatile platform chips. This class just + * retains pointers to all its children so the children can communicate. + */ + +#ifndef __DEV_ARM_VERSATILE_HH__ +#define __DEV_ARM_VERSATILE_HH__ + +#include "dev/platform.hh" +#include "params/Versatile.hh" + +class IdeController; +class System; + +class Versatile : public Platform +{ + public: + /** Pointer to the system */ + System *system; + + public: + typedef VersatileParams Params; + /** + * Constructor for the Tsunami Class. + * @param name name of the object + * @param s system the object belongs to + * @param intctrl pointer to the interrupt controller + */ + Versatile(const Params *p); + + /** + * Return the interrupting frequency to AlphaAccess + * @return frequency of RTC interrupts + */ + virtual Tick intrFrequency(); + + /** + * Cause the cpu to post a serial interrupt to the CPU. + */ + virtual void postConsoleInt(); + + /** + * Clear a posted CPU interrupt + */ + virtual void clearConsoleInt(); + + /** + * Cause the chipset to post a cpi interrupt to the CPU. + */ + virtual void postPciInt(int line); + + /** + * Clear a posted PCI->CPU interrupt + */ + virtual void clearPciInt(int line); + + + virtual Addr pciToDma(Addr pciAddr) const; + + /** + * Calculate the configuration address given a bus/dev/func. + */ + virtual Addr calcPciConfigAddr(int bus, int dev, int func); + + /** + * Calculate the address for an IO location on the PCI bus. + */ + virtual Addr calcPciIOAddr(Addr addr); + + /** + * Calculate the address for a memory location on the PCI bus. + */ + virtual Addr calcPciMemAddr(Addr addr); +}; + +#endif // __DEV_ARM_VERSATILE_HH__ diff --git a/src/dev/baddev.cc b/src/dev/baddev.cc index 6cdee0310..356574c71 100644 --- a/src/dev/baddev.cc +++ b/src/dev/baddev.cc @@ -37,6 +37,7 @@ #include <vector> #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/baddev.hh" #include "dev/platform.hh" #include "mem/port.hh" diff --git a/src/dev/ide_ctrl.cc b/src/dev/ide_ctrl.cc index a8cceda1f..87dc0b2aa 100644 --- a/src/dev/ide_ctrl.cc +++ b/src/dev/ide_ctrl.cc @@ -75,8 +75,6 @@ IdeController::Channel::Channel( IdeController::Channel::~Channel() { - delete master; - delete slave; } IdeController::IdeController(Params *p) diff --git a/src/dev/ide_disk.cc b/src/dev/ide_disk.cc index 83faf508e..fe93924f9 100644 --- a/src/dev/ide_disk.cc +++ b/src/dev/ide_disk.cc @@ -39,6 +39,7 @@ #include <string> #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "base/chunk_generator.hh" #include "base/cprintf.hh" // csprintf #include "base/trace.hh" diff --git a/src/dev/mc146818.cc b/src/dev/mc146818.cc index b25b015d2..2e6ed2a4b 100644 --- a/src/dev/mc146818.cc +++ b/src/dev/mc146818.cc @@ -105,6 +105,8 @@ MC146818::MC146818(EventManager *em, const string &n, const struct tm time, MC146818::~MC146818() { + deschedule(tickEvent); + deschedule(event); } void @@ -207,6 +209,15 @@ MC146818::serialize(const string &base, ostream &os) arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data)); paramOut(os, base + ".stat_regA", stat_regA); paramOut(os, base + ".stat_regB", stat_regB); + + // + // save the timer tick and rtc clock tick values to correctly reschedule + // them during unserialize + // + Tick rtcTimerInterruptTickOffset = event.when() - curTick; + SERIALIZE_SCALAR(rtcTimerInterruptTickOffset); + Tick rtcClockTickOffset = event.when() - curTick; + SERIALIZE_SCALAR(rtcClockTickOffset); } void @@ -218,10 +229,15 @@ MC146818::unserialize(const string &base, Checkpoint *cp, paramIn(cp, section, base + ".stat_regA", stat_regA); paramIn(cp, section, base + ".stat_regB", stat_regB); - // We're not unserializing the event here, but we need to - // rescehedule the event since curTick was moved forward by the - // checkpoint - reschedule(event, curTick + event.interval); + // + // properly schedule the timer and rtc clock events + // + Tick rtcTimerInterruptTickOffset; + UNSERIALIZE_SCALAR(rtcTimerInterruptTickOffset); + reschedule(event, curTick + rtcTimerInterruptTickOffset); + Tick rtcClockTickOffset; + UNSERIALIZE_SCALAR(rtcClockTickOffset); + reschedule(tickEvent, curTick + rtcClockTickOffset); } MC146818::RTCEvent::RTCEvent(MC146818 * _parent, Tick i) diff --git a/src/dev/mips/malta.cc b/src/dev/mips/malta.cc index 1401fe9ee..73dc9f116 100755 --- a/src/dev/mips/malta.cc +++ b/src/dev/mips/malta.cc @@ -37,6 +37,7 @@ #include <string> #include <vector> +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "dev/mips/malta_cchip.hh" #include "dev/mips/malta_pchip.hh" @@ -46,7 +47,6 @@ #include "params/Malta.hh" #include "sim/system.hh" - using namespace std; using namespace TheISA; diff --git a/src/dev/mips/malta_cchip.cc b/src/dev/mips/malta_cchip.cc index 265977665..b2d5069c5 100755 --- a/src/dev/mips/malta_cchip.cc +++ b/src/dev/mips/malta_cchip.cc @@ -39,6 +39,7 @@ #include "arch/mips/mips_core_specific.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "cpu/thread_context.hh" #include "dev/mips/malta.hh" @@ -56,7 +57,7 @@ using namespace TheISA; MaltaCChip::MaltaCChip(Params *p) : BasicPioDevice(p), malta(p->malta) { - warn("MaltaCCHIP::MaltaCChip() not implemented."); + warn("MaltaCCHIP::MaltaCChip() not implemented."); pioSize = 0xfffffff; //Put back pointer in malta diff --git a/src/dev/mips/malta_io.cc b/src/dev/mips/malta_io.cc index 7f04789db..5a738a9b4 100755 --- a/src/dev/mips/malta_io.cc +++ b/src/dev/mips/malta_io.cc @@ -42,6 +42,7 @@ #include "base/time.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/rtcreg.h" #include "dev/mips/malta_cchip.hh" #include "dev/mips/malta.hh" diff --git a/src/dev/mips/malta_pchip.cc b/src/dev/mips/malta_pchip.cc index b357e3b61..035433021 100755 --- a/src/dev/mips/malta_pchip.cc +++ b/src/dev/mips/malta_pchip.cc @@ -38,6 +38,7 @@ #include <vector> #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/mips/malta_pchip.hh" #include "dev/mips/maltareg.h" #include "dev/mips/malta.hh" diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc index 912ca7f0f..86f081ec5 100644 --- a/src/dev/ns_gige.cc +++ b/src/dev/ns_gige.cc @@ -39,6 +39,7 @@ #include "base/debug.hh" #include "base/inet.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "dev/etherlink.hh" #include "dev/ns_gige.hh" diff --git a/src/dev/platform.cc b/src/dev/platform.cc index 2b51a6245..a91a5abf9 100644 --- a/src/dev/platform.cc +++ b/src/dev/platform.cc @@ -30,6 +30,7 @@ */ #include "base/misc.hh" +#include "config/the_isa.hh" #include "dev/platform.hh" #include "sim/sim_exit.hh" diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc index 133f70b0b..86090e048 100644 --- a/src/dev/sinic.cc +++ b/src/dev/sinic.cc @@ -36,6 +36,7 @@ #include "base/debug.hh" #include "base/inet.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "cpu/thread_context.hh" #include "dev/etherlink.hh" diff --git a/src/dev/sparc/dtod.cc b/src/dev/sparc/dtod.cc index 81132ac65..c7243cfb8 100644 --- a/src/dev/sparc/dtod.cc +++ b/src/dev/sparc/dtod.cc @@ -39,6 +39,7 @@ #include "base/time.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/sparc/dtod.hh" #include "dev/platform.hh" #include "mem/packet_access.hh" diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc index 4543dd07b..40f856d8a 100644 --- a/src/dev/sparc/iob.cc +++ b/src/dev/sparc/iob.cc @@ -90,20 +90,18 @@ void Iob::readIob(PacketPtr pkt) { Addr accessAddr = pkt->getAddr() - iobManAddr; - int index; - uint64_t data; if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) { - index = (accessAddr - IntManAddr) >> 3; - data = intMan[index].cpu << 8 | intMan[index].vector << 0; + int index = (accessAddr - IntManAddr) >> 3; + uint64_t data = intMan[index].cpu << 8 | intMan[index].vector << 0; pkt->set(data); return; } if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) { - index = (accessAddr - IntManAddr) >> 3; - data = intCtl[index].mask ? 1 << 2 : 0 | - intCtl[index].pend ? 1 << 0 : 0; + int index = (accessAddr - IntCtlAddr) >> 3; + uint64_t data = intCtl[index].mask ? 1 << 2 : 0 | + intCtl[index].pend ? 1 << 0 : 0; pkt->set(data); return; } @@ -199,7 +197,7 @@ Iob::writeIob(PacketPtr pkt) } if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) { - index = (accessAddr - IntManAddr) >> 3; + index = (accessAddr - IntCtlAddr) >> 3; data = pkt->get<uint64_t>(); intCtl[index].mask = bits(data,2,2); if (bits(data,1,1)) diff --git a/src/dev/sparc/t1000.cc b/src/dev/sparc/t1000.cc index 88fb358ef..c00d942c9 100644 --- a/src/dev/sparc/t1000.cc +++ b/src/dev/sparc/t1000.cc @@ -36,6 +36,7 @@ #include <string> #include <vector> +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "dev/sparc/t1000.hh" #include "dev/terminal.hh" diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc index 93f71f49b..e3eacaaa2 100644 --- a/src/dev/uart8250.cc +++ b/src/dev/uart8250.cc @@ -38,6 +38,7 @@ #include "base/inifile.hh" #include "base/str.hh" // for to_number #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/platform.hh" #include "dev/terminal.hh" #include "dev/uart8250.hh" diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc index ed936d0cb..591fee6a4 100644 --- a/src/dev/x86/i82094aa.cc +++ b/src/dev/x86/i82094aa.cc @@ -151,7 +151,7 @@ X86ISA::I82094AA::signalInterrupt(int line) DPRINTF(I82094AA, "Entry was masked.\n"); return; } else { - TriggerIntMessage message; + TriggerIntMessage message = 0; message.destination = entry.dest; if (entry.deliveryMode == DeliveryMode::ExtInt) { assert(extIntPic); diff --git a/src/dev/x86/pc.cc b/src/dev/x86/pc.cc index 7dc1d8711..e3449abf6 100644 --- a/src/dev/x86/pc.cc +++ b/src/dev/x86/pc.cc @@ -38,6 +38,7 @@ #include "arch/x86/intmessage.hh" #include "arch/x86/x86_traits.hh" +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "dev/terminal.hh" #include "dev/x86/i82094aa.hh" diff --git a/src/kern/linux/linux.cc b/src/kern/linux/linux.cc index abe7c0b75..72f1832b8 100644 --- a/src/kern/linux/linux.cc +++ b/src/kern/linux/linux.cc @@ -28,6 +28,7 @@ * Authors: Ali Saidi */ +#include <cstdio> #include <string> #include "cpu/thread_context.hh" diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 7c16228ea..7fe107139 100644 --- a/src/kern/linux/linux.hh +++ b/src/kern/linux/linux.hh @@ -62,6 +62,7 @@ class Linux : public OperatingSystem typedef uint64_t size_t; typedef uint64_t off_t; typedef int64_t time_t; + typedef int64_t clock_t; typedef uint32_t uid_t; typedef uint32_t gid_t; //@} @@ -136,6 +137,17 @@ class Linux : public OperatingSystem int64_t tv_usec; //!< microseconds }; + /// Clock ticks per second, for times(). + static const int M5_SC_CLK_TCK = 100; + + /// For times(). + struct tms { + int64_t tms_utime; //!< user time + int64_t tms_stime; //!< system time + int64_t tms_cutime; //!< user time of children + int64_t tms_cstime; //!< system time of children + }; + // For writev/readv struct tgt_iovec { uint64_t iov_base; // void * diff --git a/src/kern/linux/printk.hh b/src/kern/linux/printk.hh index da9564b7e..5c6ee073d 100644 --- a/src/kern/linux/printk.hh +++ b/src/kern/linux/printk.hh @@ -32,8 +32,6 @@ #ifndef __PRINTK_HH__ #define __PRINTK_HH__ -#include "arch/isa_specific.hh" - #include <sstream> class Arguments; diff --git a/src/kern/operatingsystem.hh b/src/kern/operatingsystem.hh index 47e64ffd9..6574e3c6b 100644 --- a/src/kern/operatingsystem.hh +++ b/src/kern/operatingsystem.hh @@ -122,6 +122,10 @@ class OperatingSystem { static int openSpecialFile(std::string path, LiveProcess *process, ThreadContext *tc); + static const bool mmapGrowsUp = true; + + static bool mmapGrowsDown() { return false; } + }; // class OperatingSystem diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc index 6fd9e1563..bd01ed9ed 100644 --- a/src/kern/system_events.cc +++ b/src/kern/system_events.cc @@ -29,9 +29,9 @@ * Nathan Binkert */ -//For ISA_HAS_DELAY_SLOT #include "arch/isa_traits.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "kern/system_events.hh" diff --git a/src/kern/tru64/dump_mbuf.cc b/src/kern/tru64/dump_mbuf.cc index 517aad6fa..207d30792 100644 --- a/src/kern/tru64/dump_mbuf.cc +++ b/src/kern/tru64/dump_mbuf.cc @@ -37,6 +37,7 @@ #include "base/loader/symtab.hh" #include "base/trace.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "kern/tru64/mbuf.hh" #include "sim/arguments.hh" diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh index bf46e0de4..033f30946 100644 --- a/src/kern/tru64/tru64.hh +++ b/src/kern/tru64/tru64.hh @@ -31,6 +31,7 @@ #ifndef __TRU64_HH__ #define __TRU64_HH__ + #include "config/full_system.hh" #include "kern/operatingsystem.hh" @@ -55,6 +56,7 @@ class Tru64 {}; #include <string.h> // for memset() #include <unistd.h> +#include "config/the_isa.hh" #include "arch/alpha/registers.hh" #include "cpu/base.hh" #include "sim/core.hh" @@ -438,10 +440,11 @@ class Tru64 : public OperatingSystem #ifdef __CYGWIN__ panic("getdirent not implemented on cygwin!"); #else - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); - Addr tgt_buf = process->getSyscallArg(tc, 1); - int tgt_nbytes = process->getSyscallArg(tc, 2); - Addr tgt_basep = process->getSyscallArg(tc, 3); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); + Addr tgt_buf = process->getSyscallArg(tc, index); + int tgt_nbytes = process->getSyscallArg(tc, index); + Addr tgt_basep = process->getSyscallArg(tc, index); char * const host_buf = new char[tgt_nbytes]; @@ -496,7 +499,8 @@ class Tru64 : public OperatingSystem { using namespace TheISA; - TypedBufferArg<Tru64::sigcontext> sc(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<Tru64::sigcontext> sc(process->getSyscallArg(tc, index)); sc.copyIn(tc->getMemPort()); @@ -528,7 +532,8 @@ class Tru64 : public OperatingSystem { using namespace TheISA; - TypedBufferArg<Tru64::vm_stack> argp(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<Tru64::vm_stack> argp(process->getSyscallArg(tc, index)); argp.copyIn(tc->getMemPort()); @@ -576,9 +581,10 @@ class Tru64 : public OperatingSystem using namespace std; using namespace TheISA; + int index = 0; TypedBufferArg<Tru64::nxm_task_attr> - attrp(process->getSyscallArg(tc, 0)); - TypedBufferArg<Addr> configptr_ptr(process->getSyscallArg(tc, 1)); + attrp(process->getSyscallArg(tc, index)); + TypedBufferArg<Addr> configptr_ptr(process->getSyscallArg(tc, index)); attrp.copyIn(tc->getMemPort()); @@ -710,10 +716,11 @@ class Tru64 : public OperatingSystem using namespace std; using namespace TheISA; + int index = 0; TypedBufferArg<Tru64::nxm_thread_attr> - attrp(process->getSyscallArg(tc, 0)); - TypedBufferArg<uint64_t> kidp(process->getSyscallArg(tc, 1)); - int thread_index = process->getSyscallArg(tc, 2); + attrp(process->getSyscallArg(tc, index)); + TypedBufferArg<uint64_t> kidp(process->getSyscallArg(tc, index)); + int thread_index = process->getSyscallArg(tc, index); // get attribute args attrp.copyIn(tc->getMemPort()); @@ -832,11 +839,12 @@ class Tru64 : public OperatingSystem { using namespace std; - uint64_t tid = process->getSyscallArg(tc, 0); - uint64_t secs = process->getSyscallArg(tc, 1); - uint64_t flags = process->getSyscallArg(tc, 2); - uint64_t action = process->getSyscallArg(tc, 3); - uint64_t usecs = process->getSyscallArg(tc, 4); + int index = 0; + uint64_t tid = process->getSyscallArg(tc, index); + uint64_t secs = process->getSyscallArg(tc, index); + uint64_t flags = process->getSyscallArg(tc, index); + uint64_t action = process->getSyscallArg(tc, index); + uint64_t usecs = process->getSyscallArg(tc, index); cout << tc->getCpuPtr()->name() << ": nxm_thread_block " << tid << " " << secs << " " << flags << " " << action << " " << usecs << endl; @@ -851,11 +859,12 @@ class Tru64 : public OperatingSystem { using namespace std; - Addr uaddr = process->getSyscallArg(tc, 0); - uint64_t val = process->getSyscallArg(tc, 1); - uint64_t secs = process->getSyscallArg(tc, 2); - uint64_t usecs = process->getSyscallArg(tc, 3); - uint64_t flags = process->getSyscallArg(tc, 4); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); + uint64_t val = process->getSyscallArg(tc, index); + uint64_t secs = process->getSyscallArg(tc, index); + uint64_t usecs = process->getSyscallArg(tc, index); + uint64_t flags = process->getSyscallArg(tc, index); BaseCPU *cpu = tc->getCpuPtr(); @@ -874,7 +883,8 @@ class Tru64 : public OperatingSystem { using namespace std; - Addr uaddr = process->getSyscallArg(tc, 0); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); cout << tc->getCpuPtr()->name() << ": nxm_unblock " << hex << uaddr << dec << endl; @@ -975,7 +985,8 @@ class Tru64 : public OperatingSystem m5_mutex_lockFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr uaddr = process->getSyscallArg(tc, 0); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); m5_lock_mutex(uaddr, process, tc); @@ -992,7 +1003,8 @@ class Tru64 : public OperatingSystem { using namespace TheISA; - Addr uaddr = process->getSyscallArg(tc, 0); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); TypedBufferArg<uint64_t> lockp(uaddr); lockp.copyIn(tc->getMemPort()); @@ -1012,7 +1024,8 @@ class Tru64 : public OperatingSystem m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr uaddr = process->getSyscallArg(tc, 0); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); m5_unlock_mutex(uaddr, process, tc); @@ -1024,7 +1037,8 @@ class Tru64 : public OperatingSystem m5_cond_signalFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr cond_addr = process->getSyscallArg(tc, 0); + int index = 0; + Addr cond_addr = process->getSyscallArg(tc, index); // Wake up one process waiting on the condition variable. activate_waiting_context(cond_addr, process); @@ -1037,7 +1051,8 @@ class Tru64 : public OperatingSystem m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr cond_addr = process->getSyscallArg(tc, 0); + int index = 0; + Addr cond_addr = process->getSyscallArg(tc, index); activate_waiting_context(cond_addr, process, true); @@ -1051,8 +1066,9 @@ class Tru64 : public OperatingSystem { using namespace TheISA; - Addr cond_addr = process->getSyscallArg(tc, 0); - Addr lock_addr = process->getSyscallArg(tc, 1); + int index = 0; + Addr cond_addr = process->getSyscallArg(tc, index); + Addr lock_addr = process->getSyscallArg(tc, index); TypedBufferArg<uint64_t> condp(cond_addr); TypedBufferArg<uint64_t> lockp(lock_addr); @@ -1084,10 +1100,11 @@ class Tru64 : public OperatingSystem indirectSyscallFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int new_callnum = process->getSyscallArg(tc, 0); + int index = 0; + int new_callnum = process->getSyscallArg(tc, index); for (int i = 0; i < 5; ++i) - process->setSyscallArg(tc, i, process->getSyscallArg(tc, i+1)); + process->setSyscallArg(tc, i, process->getSyscallArg(tc, index)); SyscallDesc *new_desc = process->getDesc(new_callnum); diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc index 4867df559..460f75dea 100644 --- a/src/kern/tru64/tru64_events.cc +++ b/src/kern/tru64/tru64_events.cc @@ -31,6 +31,7 @@ #include "arch/alpha/ev5.hh" #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "kern/system_events.hh" diff --git a/src/mem/Bus.py b/src/mem/Bus.py index 0f113cc09..b3f6b2946 100644 --- a/src/mem/Bus.py +++ b/src/mem/Bus.py @@ -26,12 +26,12 @@ # # Authors: Nathan Binkert -from m5 import build_env +from m5.defines import buildEnv from m5.params import * from m5.proxy import * from MemObject import MemObject -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: from Device import BadAddr class Bus(MemObject): diff --git a/src/mem/RubyMemory.py b/src/mem/RubyMemory.py index fbbbeebe4..2ad794a3f 100644 --- a/src/mem/RubyMemory.py +++ b/src/mem/RubyMemory.py @@ -42,4 +42,7 @@ class RubyMemory(PhysicalMemory): debug = Param.Bool(False, "Use ruby debug") debug_file = Param.String("ruby.debug", "path to the Ruby debug output file (stdout if blank)") - + num_dmas = Param.Int(0, "Number of DMA ports connected to the Ruby memory") + dma_port = VectorPort("Ruby_dma_ports") + pio_port = Port("Ruby_pio_port") + ports_per_core = Param.Int(2, "Number of per core. Typical two: icache + dcache") diff --git a/src/mem/SConscript b/src/mem/SConscript index 21335a709..2188850e0 100644 --- a/src/mem/SConscript +++ b/src/mem/SConscript @@ -63,3 +63,4 @@ TraceFlag('BusBridge') TraceFlag('LLSC') TraceFlag('MMU') TraceFlag('MemoryAccess') +TraceFlag('Ruby') diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index cc9b83d3e..d0135fc9d 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -93,7 +93,9 @@ Bridge::init() fatal("Both ports of bus bridge are not connected to a bus.\n"); if (portA.peerBlockSize() != portB.peerBlockSize()) - fatal("Busses don't have the same block size... Not supported.\n"); + fatal("port A size %d, port B size %d \n " \ + "Busses don't have the same block size... Not supported.\n", + portA.peerBlockSize(), portB.peerBlockSize()); } bool diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 001c37a24..cac08d1a8 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -244,6 +244,9 @@ Bus::recvTiming(PacketPtr pkt) // Packet not successfully sent. Leave or put it on the retry list. // illegal to block responses... can lead to deadlock assert(!pkt->isResponse()); + // It's also illegal to force a transaction to retry after + // someone else has committed to respond. + assert(!pkt->memInhibitAsserted()); DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x TGT RETRY\n", src, pkt->getDest(), pkt->cmdString(), pkt->getAddr()); addToRetryList(src_port); diff --git a/src/mem/cache/BaseCache.py b/src/mem/cache/BaseCache.py index bdef07cb4..5ded05400 100644 --- a/src/mem/cache/BaseCache.py +++ b/src/mem/cache/BaseCache.py @@ -68,8 +68,6 @@ class BaseCache(MemObject): "Latency of the prefetcher") prefetch_policy = Param.Prefetch('none', "Type of prefetcher to use") - prefetch_cache_check_push = Param.Bool(True, - "Check if in cache on push or pop of prefetch queue") prefetch_use_cpu_id = Param.Bool(True, "Use the CPU ID to separate calculations of prefetches") prefetch_data_accesses_only = Param.Bool(False, diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh index 24f993383..c245fecd2 100644 --- a/src/mem/cache/base.hh +++ b/src/mem/cache/base.hh @@ -379,7 +379,7 @@ class BaseCache : public MemObject } - Addr blockAlign(Addr addr) const { return (addr & ~(blkSize - 1)); } + Addr blockAlign(Addr addr) const { return (addr & ~(Addr(blkSize - 1))); } const Range<Addr> &getAddrRange() const { return addrRange; } diff --git a/src/mem/cache/builder.cc b/src/mem/cache/builder.cc index 599353b88..bd9eb9acc 100644 --- a/src/mem/cache/builder.cc +++ b/src/mem/cache/builder.cc @@ -33,9 +33,10 @@ * @file * Simobject instatiation of caches. */ +#include <list> #include <vector> -// Must be included first to determine which caches we want +#include "config/the_isa.hh" #include "enums/Prefetch.hh" #include "mem/config/cache.hh" #include "mem/cache/base.hh" diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 80b7c545c..429928c79 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -449,7 +449,7 @@ Cache<TagStore>::timingAccess(PacketPtr pkt) } else { // miss - Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); + Addr blk_addr = blockAlign(pkt->getAddr()); MSHR *mshr = mshrQueue.findMatch(blk_addr); if (mshr) { @@ -692,7 +692,7 @@ Cache<TagStore>::functionalAccess(PacketPtr pkt, CachePort *incomingPort, CachePort *otherSidePort) { - Addr blk_addr = pkt->getAddr() & ~(blkSize - 1); + Addr blk_addr = blockAlign(pkt->getAddr()); BlkType *blk = tags->findBlock(pkt->getAddr()); pkt->pushLabel(name()); @@ -1162,7 +1162,7 @@ Cache<TagStore>::snoopTiming(PacketPtr pkt) BlkType *blk = tags->findBlock(pkt->getAddr()); - Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); + Addr blk_addr = blockAlign(pkt->getAddr()); MSHR *mshr = mshrQueue.findMatch(blk_addr); // Let the MSHR itself track the snoop and decide whether we want @@ -1301,11 +1301,14 @@ Cache<TagStore>::getNextMSHR() // If we have a miss queue slot, we can try a prefetch PacketPtr pkt = prefetcher->getPacket(); if (pkt) { - // Update statistic on number of prefetches issued - // (hwpf_mshr_misses) - mshr_misses[pkt->cmdToIndex()][0/*pkt->req->threadId()*/]++; - // Don't request bus, since we already have it - return allocateMissBuffer(pkt, curTick, false); + Addr pf_addr = blockAlign(pkt->getAddr()); + if (!tags->findBlock(pf_addr) && !mshrQueue.findMatch(pf_addr)) { + // Update statistic on number of prefetches issued + // (hwpf_mshr_misses) + mshr_misses[pkt->cmdToIndex()][0/*pkt->req->threadId()*/]++; + // Don't request bus, since we already have it + return allocateMissBuffer(pkt, curTick, false); + } } } diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc index f20a306cb..ad7a0c882 100644 --- a/src/mem/cache/prefetch/base.cc +++ b/src/mem/cache/prefetch/base.cc @@ -33,17 +33,18 @@ * Hardware Prefetcher Definition. */ +#include <list> + #include "arch/isa_traits.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "mem/cache/base.hh" #include "mem/cache/prefetch/base.hh" #include "mem/request.hh" -#include <list> BasePrefetcher::BasePrefetcher(const BaseCacheParams *p) : size(p->prefetcher_size), pageStop(!p->prefetch_past_page), serialSquash(p->prefetch_serial_squash), - cacheCheckPush(p->prefetch_cache_check_push), onlyData(p->prefetch_data_accesses_only) { } @@ -141,9 +142,6 @@ BasePrefetcher::getPacket() do { pkt = *pf.begin(); pf.pop_front(); - if (!cacheCheckPush) { - keep_trying = cache->inCache(pkt->getAddr()); - } if (keep_trying) { DPRINTF(HWPrefetch, "addr 0x%x in cache, skipping\n", @@ -224,18 +222,6 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick time) "inserting into prefetch queue with delay %d time %d\n", addr, *delayIter, time); - // Check if it is already in the cache - if (cacheCheckPush && cache->inCache(addr)) { - DPRINTF(HWPrefetch, "Prefetch addr already in cache\n"); - continue; - } - - // Check if it is already in the miss_queue - if (cache->inMissQueue(addr)) { - DPRINTF(HWPrefetch, "Prefetch addr already in miss queue\n"); - continue; - } - // Check if it is already in the pf buffer if (inPrefetch(addr) != pf.end()) { pfBufferHit++; diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh index b5f33a455..e3c0cbf16 100644 --- a/src/mem/cache/prefetch/base.hh +++ b/src/mem/cache/prefetch/base.hh @@ -68,10 +68,6 @@ class BasePrefetcher /** Do we remove prefetches with later times than a new miss.*/ bool serialSquash; - /** Do we check if it is in the cache when inserting into buffer, - or removing.*/ - bool cacheCheckPush; - /** Do we prefetch on only data reads, or on inst reads as well. */ bool onlyData; diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 07c086cd5..c58862270 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -437,6 +437,7 @@ class Packet : public FastAlloc, public Printable bool hadBadAddress() const { return cmd == MemCmd::BadAddressError; } void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; } + bool isSrcValid() { return flags.isSet(VALID_SRC); } /// Accessor function to get the source index of the packet. NodeID getSrc() const { assert(flags.isSet(VALID_SRC)); return src; } /// Accessor function to set the source index of the packet. @@ -444,6 +445,7 @@ class Packet : public FastAlloc, public Printable /// Reset source field, e.g. to retransmit packet on different bus. void clearSrc() { flags.clear(VALID_SRC); } + bool isDestValid() { return flags.isSet(VALID_DST); } /// Accessor function for the destination index of the packet. NodeID getDest() const { assert(flags.isSet(VALID_DST)); return dest; } /// Accessor function to set the destination index of the packet. diff --git a/src/mem/packet_access.hh b/src/mem/packet_access.hh index f70d508b2..fca9606fc 100644 --- a/src/mem/packet_access.hh +++ b/src/mem/packet_access.hh @@ -31,6 +31,7 @@ #include "arch/isa_traits.hh" #include "base/bigint.hh" +#include "config/the_isa.hh" #include "mem/packet.hh" #include "sim/byteswap.hh" diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index bf35932a6..4bc3a4434 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -42,6 +42,7 @@ #include "base/bitfield.hh" #include "base/intmath.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "mem/page_table.hh" #include "sim/process.hh" #include "sim/sim_object.hh" diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index 3ce720ad4..0d93d37c7 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -42,6 +42,7 @@ #include "arch/tlb.hh" #include "base/hashmap.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "mem/request.hh" #include "sim/faults.hh" #include "sim/serialize.hh" diff --git a/src/mem/physical.cc b/src/mem/physical.cc index d87ad3b22..121a6e447 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -36,6 +36,7 @@ #include <unistd.h> #include <zlib.h> +#include <cstdio> #include <iostream> #include <string> @@ -44,6 +45,7 @@ #include "base/random.hh" #include "base/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "mem/packet_access.hh" #include "mem/physical.hh" #include "sim/eventq.hh" diff --git a/src/mem/port_impl.hh b/src/mem/port_impl.hh index 989cfd338..bc9592164 100644 --- a/src/mem/port_impl.hh +++ b/src/mem/port_impl.hh @@ -28,9 +28,8 @@ * Authors: Ali Saidi */ -//To get endianness #include "arch/isa_traits.hh" - +#include "config/the_isa.hh" #include "mem/port.hh" #include "sim/byteswap.hh" diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm index 17f39af5b..1f64d25df 100644 --- a/src/mem/protocol/MI_example-dir.sm +++ b/src/mem/protocol/MI_example-dir.sm @@ -1,8 +1,6 @@ machine(Directory, "Directory protocol") -: int directory_latency, - int dma_select_low_bit, - int dma_select_num_bits +: int directory_latency { MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false"; @@ -74,6 +72,7 @@ machine(Directory, "Directory protocol") State TBEState, desc="Transient State"; DataBlock DataBlk, desc="Data to be written (DMA write only)"; int Len, desc="..."; + MachineID DmaRequestor, desc="DMA requestor"; } external_type(TBETable) { @@ -243,8 +242,7 @@ machine(Directory, "Directory protocol") out_msg.LineAddress := address; out_msg.Type := DMAResponseType:DATA; out_msg.DataBlk := in_msg.DataBlk; // we send the entire data block and rely on the dma controller to split it up if need be - out_msg.Destination.add(mapAddressToRange(address, MachineType:DMA, - dma_select_low_bit, dma_select_num_bits)); + out_msg.Destination.add(TBEs[address].DmaRequestor); out_msg.MessageSize := MessageSizeType:Response_Data; } } @@ -259,8 +257,7 @@ machine(Directory, "Directory protocol") out_msg.LineAddress := address; out_msg.Type := DMAResponseType:DATA; out_msg.DataBlk := in_msg.DataBlk; // we send the entire data block and rely on the dma controller to split it up if need be - out_msg.Destination.add(mapAddressToRange(address, MachineType:DMA, - dma_select_low_bit, dma_select_num_bits)); + out_msg.Destination.add(TBEs[address].DmaRequestor); out_msg.MessageSize := MessageSizeType:Response_Data; } } @@ -271,8 +268,7 @@ machine(Directory, "Directory protocol") out_msg.PhysicalAddress := address; out_msg.LineAddress := address; out_msg.Type := DMAResponseType:ACK; - out_msg.Destination.add(mapAddressToRange(address, MachineType:DMA, - dma_select_low_bit, dma_select_num_bits)); + out_msg.Destination.add(TBEs[address].DmaRequestor); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -343,6 +339,14 @@ machine(Directory, "Directory protocol") TBEs[address].DataBlk := in_msg.DataBlk; TBEs[address].PhysicalAddress := in_msg.PhysicalAddress; TBEs[address].Len := in_msg.Len; + TBEs[address].DmaRequestor := in_msg.Requestor; + } + } + + action(r_allocateTbeForDmaRead, "\r", desc="Allocate TBE for DMA Read") { + peek(dmaRequestQueue_in, DMARequestMsg) { + TBEs.allocate(address); + TBEs[address].DmaRequestor := in_msg.Requestor; } } @@ -485,6 +489,7 @@ machine(Directory, "Directory protocol") transition(I, DMA_READ, ID) { //dr_sendDMAData; + r_allocateTbeForDmaRead; qf_queueMemoryFetchRequestDMA; p_popIncomingDMARequestQueue; } @@ -492,6 +497,7 @@ machine(Directory, "Directory protocol") transition(ID, Memory_Data, I) { dr_sendDMAData; //p_popIncomingDMARequestQueue; + w_deallocateTBE; l_popMemQueue; } diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm index e883288df..79c42e719 100644 --- a/src/mem/protocol/MI_example-dma.sm +++ b/src/mem/protocol/MI_example-dma.sm @@ -71,6 +71,7 @@ machine(DMA, "DMA Controller") out_msg.PhysicalAddress := in_msg.PhysicalAddress; out_msg.LineAddress := in_msg.LineAddress; out_msg.Type := DMARequestType:READ; + out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; out_msg.Destination.add(map_Address_to_Directory(address)); @@ -85,6 +86,7 @@ machine(DMA, "DMA Controller") out_msg.PhysicalAddress := in_msg.PhysicalAddress; out_msg.LineAddress := in_msg.LineAddress; out_msg.Type := DMARequestType:WRITE; + out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; out_msg.Destination.add(map_Address_to_Directory(address)); @@ -113,10 +115,6 @@ machine(DMA, "DMA Controller") dmaResponseQueue_in.dequeue(); } - action(z_stall, "z", desc="dma is busy..stall") { - // do nothing - } - transition(READY, ReadRequest, BUSY_RD) { s_sendReadRequest; p_popRequestQueue; diff --git a/src/mem/protocol/MI_example-msg.sm b/src/mem/protocol/MI_example-msg.sm index d4d557200..3cdb74e49 100644 --- a/src/mem/protocol/MI_example-msg.sm +++ b/src/mem/protocol/MI_example-msg.sm @@ -105,6 +105,7 @@ structure(DMARequestMsg, desc="...", interface="NetworkMessage") { DMARequestType Type, desc="Request type (read/write)"; Address PhysicalAddress, desc="Physical address for this request"; Address LineAddress, desc="Line address for this request"; + MachineID Requestor, desc="Node who initiated the request"; NetDest Destination, desc="Destination"; DataBlock DataBlk, desc="DataBlk attached to this request"; int Len, desc="The length of the request"; diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index ab58c5c00..3fb4a8862 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -32,21 +32,32 @@ * */ -machine(L1Cache, "Token protocol") { +machine(L1Cache, "Token protocol") + : int l1_request_latency, + int l1_response_latency, + int l2_select_low_bit, + int l2_select_num_bits, + int N_tokens, + int retry_threshold, + int fixed_timeout_latency, + bool dynamic_timeout_enabled +{ // From this node's L1 cache TO the network - // a local L1 -> this L2 bank, currently ordered with directory forwarded requests - MessageBuffer requestFromL1Cache, network="To", virtual_network="0", ordered="false"; + // a local L1 -> this L2 bank - MessageBuffer responseFromL1Cache, network="To", virtual_network="2", ordered="false"; - MessageBuffer persistentFromL1Cache, network="To", virtual_network="3", ordered="true"; + MessageBuffer responseFromL1Cache, network="To", virtual_network="1", ordered="false"; + MessageBuffer persistentFromL1Cache, network="To", virtual_network="2", ordered="true"; + // a local L1 -> this L2 bank, currently ordered with directory forwarded requests + MessageBuffer requestFromL1Cache, network="To", virtual_network="4", ordered="false"; + // To this node's L1 cache FROM the network // a L2 bank -> this L1 - MessageBuffer requestToL1Cache, network="From", virtual_network="0", ordered="false"; + MessageBuffer responseToL1Cache, network="From", virtual_network="1", ordered="false"; + MessageBuffer persistentToL1Cache, network="From", virtual_network="2", ordered="true"; // a L2 bank -> this L1 - MessageBuffer responseToL1Cache, network="From", virtual_network="2", ordered="false"; - MessageBuffer persistentToL1Cache, network="From", virtual_network="3", ordered="true"; + MessageBuffer requestToL1Cache, network="From", virtual_network="4", ordered="false"; // STATES enumeration(State, desc="Cache states", default="L1Cache_State_I") { @@ -111,10 +122,6 @@ machine(L1Cache, "Token protocol") { // TYPES - int getRetryThreshold(); - int getFixedTimeoutLatency(); - bool getDynamicTimeoutEnabled(); - // CacheEntry structure(Entry, desc="...", interface="AbstractCacheEntry") { State CacheState, desc="cache state"; @@ -143,7 +150,7 @@ machine(L1Cache, "Token protocol") { external_type(CacheMemory) { bool cacheAvail(Address); Address cacheProbe(Address); - void allocate(Address); + void allocate(Address, Entry); void deallocate(Address); Entry lookup(Address); void changePermission(Address, AccessPermission); @@ -157,17 +164,28 @@ machine(L1Cache, "Token protocol") { bool isPresent(Address); } + external_type(PersistentTable) { + void persistentRequestLock(Address, MachineID, AccessType); + void persistentRequestUnlock(Address, MachineID); + bool okToIssueStarving(Address, MachineID); + MachineID findSmallest(Address); + AccessType typeOfSmallest(Address); + void markEntries(Address); + bool isLocked(Address); + int countStarvingForAddress(Address); + int countReadStarvingForAddress(Address); + } TBETable L1_TBEs, template_hack="<L1Cache_TBE>"; - CacheMemory L1IcacheMemory, template_hack="<L1Cache_Entry>", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1I"', abstract_chip_ptr="true"; - CacheMemory L1DcacheMemory, template_hack="<L1Cache_Entry>", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1D"', abstract_chip_ptr="true"; + CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])'; + CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])'; MessageBuffer mandatoryQueue, ordered="false", abstract_chip_ptr="true"; - Sequencer sequencer, abstract_chip_ptr="true", constructor_hack="i"; + Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])'; bool starving, default="false"; - PersistentTable persistentTable, constructor_hack="i"; + PersistentTable persistentTable; TimerTable useTimerTable; TimerTable reissueTimerTable; @@ -175,11 +193,11 @@ machine(L1Cache, "Token protocol") { int outstandingPersistentRequests, default="0"; int averageLatencyHysteresis, default="(8)"; // Constant that provides hysteresis for calculated the estimated average - int averageLatencyCounter, default="(500 << (*m_L1Cache_averageLatencyHysteresis_vec[i]))"; + int averageLatencyCounter, default="(500 << (*m_L1Cache_averageLatencyHysteresis_ptr))"; int averageLatencyEstimate() { DEBUG_EXPR( (averageLatencyCounter >> averageLatencyHysteresis) ); - profile_average_latency_estimate( (averageLatencyCounter >> averageLatencyHysteresis) ); + //profile_average_latency_estimate( (averageLatencyCounter >> averageLatencyHysteresis) ); return averageLatencyCounter >> averageLatencyHysteresis; } @@ -366,30 +384,33 @@ machine(L1Cache, "Token protocol") { } } - GenericMachineType getNondirectHitMachType(Address addr, MachineID sender) { - if (machineIDToMachineType(sender) == MachineType:L1Cache) { - return GenericMachineType:L1Cache_wCC; // NOTE direct L1 hits should not call this - } else if (machineIDToMachineType(sender) == MachineType:L2Cache) { - if ( sender == (map_L1CacheMachId_to_L2Cache(addr,machineID))) { - return GenericMachineType:L2Cache; - } else { - return GenericMachineType:L2Cache_wCC; - } - } else { - return ConvertMachToGenericMach(machineIDToMachineType(sender)); - } - } - - bool okToIssueStarving(Address addr) { - return persistentTable.okToIssueStarving(addr); +// GenericMachineType getNondirectHitMachType(Address addr, MachineID sender) { +// if (machineIDToMachineType(sender) == MachineType:L1Cache) { +// return GenericMachineType:L1Cache_wCC; // NOTE direct L1 hits should not call this +// } else if (machineIDToMachineType(sender) == MachineType:L2Cache) { +// +// if (sender == (mapAddressToRange(addr, +// MachineType:L2Cache, +// l2_select_low_bit, +// l2_select_num_bits))) { +// +// return GenericMachineType:L2Cache; +// } else { +// return GenericMachineType:L2Cache_wCC; +// } +// } else { +// return ConvertMachToGenericMach(machineIDToMachineType(sender)); +// } +// } + + bool okToIssueStarving(Address addr, MachineID machinID) { + return persistentTable.okToIssueStarving(addr, machineID); } void markPersistentEntries(Address addr) { persistentTable.markEntries(addr); } - MessageBuffer triggerQueue, ordered="false", random="false"; - // ** OUT_PORTS ** out_port(persistentNetwork_out, PersistentMsg, persistentFromL1Cache); out_port(requestNetwork_out, RequestMsg, requestFromL1Cache); @@ -507,7 +528,11 @@ machine(L1Cache, "Token protocol") { // Mark TBE flag if response received off-chip. Use this to update average latency estimate if ( in_msg.SenderMachine == MachineType:L2Cache ) { - if (in_msg.Sender == map_L1CacheMachId_to_L2Cache(in_msg.Address, machineID)) { + if (in_msg.Sender == mapAddressToRange(in_msg.Address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)) { + // came from an off-chip L2 cache if (L1_TBEs.isPresent(in_msg.Address)) { // L1_TBEs[in_msg.Address].ExternalResponse := true; @@ -523,15 +548,15 @@ machine(L1Cache, "Token protocol") { // profile_memory_response( in_msg.Address); } } else if ( in_msg.SenderMachine == MachineType:L1Cache) { - if (isLocalProcessor(machineID, in_msg.Sender) == false) { - if (L1_TBEs.isPresent(in_msg.Address)) { + //if (isLocalProcessor(machineID, in_msg.Sender) == false) { + //if (L1_TBEs.isPresent(in_msg.Address)) { // L1_TBEs[in_msg.Address].ExternalResponse := true; // profile_offchipL1_response(in_msg.Address ); - } - } - else { + //} + //} + //else { // profile_onchipL1_response(in_msg.Address ); - } + //} } else { error("unexpected SenderMachine"); } @@ -570,42 +595,42 @@ machine(L1Cache, "Token protocol") { // ** INSTRUCTION ACCESS *** // Check to see if it is in the OTHER L1 - if (L1DcacheMemory.isTagPresent(in_msg.Address)) { + if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) { // The block is in the wrong L1, try to write it to the L2 - trigger(Event:L1_Replacement, in_msg.Address); + trigger(Event:L1_Replacement, in_msg.LineAddress); } - if (L1IcacheMemory.isTagPresent(in_msg.Address)) { + if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) { // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { - if (L1IcacheMemory.cacheAvail(in_msg.Address)) { + if (L1IcacheMemory.cacheAvail(in_msg.LineAddress)) { // L1 does't have the line, but we have space for it in the L1 - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { // No room in the L1, so we need to make room - trigger(Event:L1_Replacement, L1IcacheMemory.cacheProbe(in_msg.Address)); + trigger(Event:L1_Replacement, L1IcacheMemory.cacheProbe(in_msg.LineAddress)); } } } else { // *** DATA ACCESS *** // Check to see if it is in the OTHER L1 - if (L1IcacheMemory.isTagPresent(in_msg.Address)) { + if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) { // The block is in the wrong L1, try to write it to the L2 - trigger(Event:L1_Replacement, in_msg.Address); + trigger(Event:L1_Replacement, in_msg.LineAddress); } - if (L1DcacheMemory.isTagPresent(in_msg.Address)) { + if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) { // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { - if (L1DcacheMemory.cacheAvail(in_msg.Address)) { + if (L1DcacheMemory.cacheAvail(in_msg.LineAddress)) { // L1 does't have the line, but we have space for it in the L1 - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { // No room in the L1, so we need to make room - trigger(Event:L1_Replacement, L1DcacheMemory.cacheProbe(in_msg.Address)); + trigger(Event:L1_Replacement, L1DcacheMemory.cacheProbe(in_msg.LineAddress)); } } } @@ -618,19 +643,31 @@ machine(L1Cache, "Token protocol") { action(a_issueReadRequest, "a", desc="Issue GETS") { if (L1_TBEs[address].IssueCount == 0) { // Update outstanding requests - profile_outstanding_request(outstandingRequests); + //profile_outstanding_request(outstandingRequests); outstandingRequests := outstandingRequests + 1; } - if (L1_TBEs[address].IssueCount >= getRetryThreshold() ) { + if (L1_TBEs[address].IssueCount >= retry_threshold) { // Issue a persistent request if possible - if (okToIssueStarving(address) && (starving == false)) { - enqueue(persistentNetwork_out, PersistentMsg, latency="L1_REQUEST_LATENCY") { + if (okToIssueStarving(address, machineID) && (starving == false)) { + enqueue(persistentNetwork_out, PersistentMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := PersistentRequestType:GETS_PERSISTENT; out_msg.Requestor := machineID; out_msg.Destination.broadcast(MachineType:L1Cache); - out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := L1_TBEs[address].Prefetch; @@ -640,11 +677,11 @@ machine(L1Cache, "Token protocol") { starving := true; if (L1_TBEs[address].IssueCount == 0) { - profile_persistent_prediction(address, L1_TBEs[address].AccessType); + //profile_persistent_prediction(address, L1_TBEs[address].AccessType); } // Update outstanding requests - profile_outstanding_persistent_request(outstandingPersistentRequests); + //profile_outstanding_persistent_request(outstandingPersistentRequests); outstandingPersistentRequests := outstandingPersistentRequests + 1; // Increment IssueCount @@ -666,11 +703,16 @@ machine(L1Cache, "Token protocol") { } } else { // Make a normal request - enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETS; out_msg.Requestor := machineID; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.RetryNum := L1_TBEs[address].IssueCount; if (L1_TBEs[address].IssueCount == 0) { out_msg.MessageSize := MessageSizeType:Request_Control; @@ -682,11 +724,18 @@ machine(L1Cache, "Token protocol") { } // send to other local L1s, with local bit set - enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETS; out_msg.Requestor := machineID; - out_msg.Destination := getOtherLocalL1IDs(machineID); + + // + // Since only one chip, assuming all L1 caches are local + // + //out_msg.Destination := getOtherLocalL1IDs(machineID); + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.remove(machineID); + out_msg.RetryNum := L1_TBEs[address].IssueCount; out_msg.isLocal := true; if (L1_TBEs[address].IssueCount == 0) { @@ -703,10 +752,10 @@ machine(L1Cache, "Token protocol") { // Set a wakeup timer - if (getDynamicTimeoutEnabled()) { + if (dynamic_timeout_enabled) { reissueTimerTable.set(address, 1.25 * averageLatencyEstimate()); } else { - reissueTimerTable.set(address, getFixedTimeoutLatency()); + reissueTimerTable.set(address, fixed_timeout_latency); } } @@ -716,20 +765,32 @@ machine(L1Cache, "Token protocol") { if (L1_TBEs[address].IssueCount == 0) { // Update outstanding requests - profile_outstanding_request(outstandingRequests); + //profile_outstanding_request(outstandingRequests); outstandingRequests := outstandingRequests + 1; } - if (L1_TBEs[address].IssueCount >= getRetryThreshold() ) { + if (L1_TBEs[address].IssueCount >= retry_threshold) { // Issue a persistent request if possible - if ( okToIssueStarving(address) && (starving == false)) { - enqueue(persistentNetwork_out, PersistentMsg, latency="L1_REQUEST_LATENCY") { + if ( okToIssueStarving(address, machineID) && (starving == false)) { + enqueue(persistentNetwork_out, PersistentMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := PersistentRequestType:GETX_PERSISTENT; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L1Cache; out_msg.Destination.broadcast(MachineType:L1Cache); - out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := L1_TBEs[address].Prefetch; @@ -739,11 +800,11 @@ machine(L1Cache, "Token protocol") { starving := true; // Update outstanding requests - profile_outstanding_persistent_request(outstandingPersistentRequests); + //profile_outstanding_persistent_request(outstandingPersistentRequests); outstandingPersistentRequests := outstandingPersistentRequests + 1; if (L1_TBEs[address].IssueCount == 0) { - profile_persistent_prediction(address, L1_TBEs[address].AccessType); + //profile_persistent_prediction(address, L1_TBEs[address].AccessType); } // Increment IssueCount @@ -766,12 +827,17 @@ machine(L1Cache, "Token protocol") { } else { // Make a normal request - enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L1Cache; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.RetryNum := L1_TBEs[address].IssueCount; if (L1_TBEs[address].IssueCount == 0) { @@ -784,12 +850,19 @@ machine(L1Cache, "Token protocol") { } // send to other local L1s too - enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; out_msg.isLocal := true; - out_msg.Destination := getOtherLocalL1IDs(machineID); + + // + // Since only one chip, assuming all L1 caches are local + // + //out_msg.Destination := getOtherLocalL1IDs(machineID); + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.remove(machineID); + out_msg.RetryNum := L1_TBEs[address].IssueCount; if (L1_TBEs[address].IssueCount == 0) { out_msg.MessageSize := MessageSizeType:Request_Control; @@ -807,10 +880,10 @@ machine(L1Cache, "Token protocol") { DEBUG_EXPR(L1_TBEs[address].IssueCount); // Set a wakeup timer - if (getDynamicTimeoutEnabled()) { + if (dynamic_timeout_enabled) { reissueTimerTable.set(address, 1.25 * averageLatencyEstimate()); } else { - reissueTimerTable.set(address, getFixedTimeoutLatency()); + reissueTimerTable.set(address, fixed_timeout_latency); } } } @@ -818,7 +891,7 @@ machine(L1Cache, "Token protocol") { action(bb_bounceResponse, "\b", desc="Bounce tokens and data to memory") { peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -833,11 +906,16 @@ machine(L1Cache, "Token protocol") { } action(c_ownedReplacement, "c", desc="Issue writeback") { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Tokens := getCacheEntry(address).Tokens; out_msg.DataBlk := getCacheEntry(address).DataBlk; out_msg.Dirty := getCacheEntry(address).Dirty; @@ -853,11 +931,16 @@ machine(L1Cache, "Token protocol") { // don't send writeback if replacing block with no tokens if (getCacheEntry(address).Tokens != 0) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Tokens := getCacheEntry(address).Tokens; out_msg.DataBlk := getCacheEntry(address).DataBlk; // assert(getCacheEntry(address).Dirty == false); @@ -879,7 +962,7 @@ machine(L1Cache, "Token protocol") { action(d_sendDataWithToken, "d", desc="Send data and a token from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; @@ -902,14 +985,14 @@ machine(L1Cache, "Token protocol") { action(d_sendDataWithNTokenIfAvail, "\dd", desc="Send data and a token from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - if (getCacheEntry(address).Tokens > N_tokens()) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + if (getCacheEntry(address).Tokens > N_tokens) { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; out_msg.Destination.add(in_msg.Requestor); - out_msg.Tokens := N_tokens(); + out_msg.Tokens := N_tokens; out_msg.DataBlk := getCacheEntry(address).DataBlk; // out_msg.Dirty := getCacheEntry(address).Dirty; out_msg.Dirty := false; @@ -919,10 +1002,10 @@ machine(L1Cache, "Token protocol") { out_msg.MessageSize := MessageSizeType:Response_Data; } } - getCacheEntry(address).Tokens := getCacheEntry(address).Tokens - N_tokens(); + getCacheEntry(address).Tokens := getCacheEntry(address).Tokens - N_tokens; } else if (getCacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; @@ -946,7 +1029,7 @@ machine(L1Cache, "Token protocol") { action(dd_sendDataWithAllTokens, "\d", desc="Send data and all tokens from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -969,7 +1052,7 @@ machine(L1Cache, "Token protocol") { action(e_sendAckWithCollectedTokens, "e", desc="Send ack with the tokens we've collected thus far.") { // assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself if (getCacheEntry(address).Tokens > 0) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -986,7 +1069,7 @@ machine(L1Cache, "Token protocol") { action(ee_sendDataWithAllTokens, "\e", desc="Send data and all tokens from cache to starver") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getCacheEntry(address).Tokens > 0); - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -1005,23 +1088,23 @@ machine(L1Cache, "Token protocol") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getCacheEntry(address).Tokens > 0); if (getCacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; out_msg.Destination.add(persistentTable.findSmallest(address)); assert(getCacheEntry(address).Tokens >= 1); - if (getCacheEntry(address).Tokens > N_tokens()) { - out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens(); + if (getCacheEntry(address).Tokens > N_tokens) { + out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens; } else { out_msg.Tokens := getCacheEntry(address).Tokens - 1; } out_msg.MessageSize := MessageSizeType:Response_Control; } } - if (getCacheEntry(address).Tokens > N_tokens()) { - getCacheEntry(address).Tokens := N_tokens(); + if (getCacheEntry(address).Tokens > N_tokens) { + getCacheEntry(address).Tokens := N_tokens; } else { getCacheEntry(address).Tokens := 1; } @@ -1031,15 +1114,15 @@ machine(L1Cache, "Token protocol") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getCacheEntry(address).Tokens > 0); if (getCacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; out_msg.Destination.add(persistentTable.findSmallest(address)); assert(getCacheEntry(address).Tokens >= 1); - if (getCacheEntry(address).Tokens > N_tokens()) { - out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens(); + if (getCacheEntry(address).Tokens > N_tokens) { + out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens; } else { out_msg.Tokens := getCacheEntry(address).Tokens - 1; } @@ -1047,8 +1130,8 @@ machine(L1Cache, "Token protocol") { out_msg.Dirty := getCacheEntry(address).Dirty; out_msg.MessageSize := MessageSizeType:Response_Data; } - if (getCacheEntry(address).Tokens > N_tokens()) { - getCacheEntry(address).Tokens := N_tokens(); + if (getCacheEntry(address).Tokens > N_tokens) { + getCacheEntry(address).Tokens := N_tokens; } else { getCacheEntry(address).Tokens := 1; } @@ -1061,7 +1144,7 @@ machine(L1Cache, "Token protocol") { peek(responseNetwork_in, ResponseMsg) { // assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself // FIXME, should use a 3rd vnet in some cases - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -1079,7 +1162,8 @@ machine(L1Cache, "Token protocol") { action(h_load_hit, "h", desc="Notify sequencer the load completed.") { DEBUG_EXPR(address); DEBUG_EXPR(getCacheEntry(address).DataBlk); - sequencer.readCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No); + //sequencer.readCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No); + sequencer.readCallback(address, getCacheEntry(address).DataBlk); } action(x_external_load_hit, "x", desc="Notify sequencer the load completed.") { @@ -1087,14 +1171,16 @@ machine(L1Cache, "Token protocol") { DEBUG_EXPR(getCacheEntry(address).DataBlk); peek(responseNetwork_in, ResponseMsg) { - sequencer.readCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No); + //sequencer.readCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No); + sequencer.readCallback(address, getCacheEntry(address).DataBlk); } } action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") { DEBUG_EXPR(address); DEBUG_EXPR(getCacheEntry(address).DataBlk); - sequencer.writeCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No); + //sequencer.writeCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No); + sequencer.writeCallback(address, getCacheEntry(address).DataBlk); getCacheEntry(address).Dirty := true; DEBUG_EXPR(getCacheEntry(address).DataBlk); } @@ -1103,7 +1189,8 @@ machine(L1Cache, "Token protocol") { DEBUG_EXPR(address); DEBUG_EXPR(getCacheEntry(address).DataBlk); peek(responseNetwork_in, ResponseMsg) { - sequencer.writeCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No); + //sequencer.writeCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No); + sequencer.writeCallback(address, getCacheEntry(address).DataBlk); } getCacheEntry(address).Dirty := true; DEBUG_EXPR(getCacheEntry(address).DataBlk); @@ -1133,8 +1220,6 @@ machine(L1Cache, "Token protocol") { useTimerTable.unset(address); } - - action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") { mandatoryQueue_in.dequeue(); } @@ -1156,14 +1241,19 @@ machine(L1Cache, "Token protocol") { } action(p_informL2AboutTokenLoss, "p", desc="Inform L2 about loss of all tokens") { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:INV; out_msg.Tokens := 0; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; out_msg.DestMachine := MachineType:L2Cache; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.MessageSize := MessageSizeType:Response_Control; } } @@ -1189,13 +1279,25 @@ machine(L1Cache, "Token protocol") { if (L1_TBEs[address].WentPersistent) { // assert(starving == true); outstandingRequests := outstandingRequests - 1; - enqueue(persistentNetwork_out, PersistentMsg, latency="L1_REQUEST_LATENCY") { + enqueue(persistentNetwork_out, PersistentMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := PersistentRequestType:DEACTIVATE_PERSISTENT; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L1Cache; out_msg.Destination.broadcast(MachineType:L1Cache); - out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Persistent_Control; } @@ -1217,14 +1319,14 @@ machine(L1Cache, "Token protocol") { // profile_token_retry(address, L1_TBEs[address].AccessType, 1); //} - profile_token_retry(address, L1_TBEs[address].AccessType, L1_TBEs[address].IssueCount); + //profile_token_retry(address, L1_TBEs[address].AccessType, L1_TBEs[address].IssueCount); L1_TBEs.deallocate(address); } action(t_sendAckWithCollectedTokens, "t", desc="Send ack with the tokens we've collected thus far.") { if (getCacheEntry(address).Tokens > 0) { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -1259,13 +1361,13 @@ machine(L1Cache, "Token protocol") { action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") { if (L1DcacheMemory.isTagPresent(address) == false) { - L1DcacheMemory.allocate(address); + L1DcacheMemory.allocate(address, new Entry); } } action(pp_allocateL1ICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B.") { if (L1IcacheMemory.isTagPresent(address) == false) { - L1IcacheMemory.allocate(address); + L1IcacheMemory.allocate(address, new Entry); } } @@ -1281,11 +1383,6 @@ machine(L1Cache, "Token protocol") { } } - - action(z_stall, "z", desc="Stall") { - - } - action(zz_recycleMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") { mandatoryQueue_in.recycle(); } diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm index 0a58ed5cf..9a5c400f2 100644 --- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm @@ -32,20 +32,33 @@ * */ -machine(L2Cache, "Token protocol") { +machine(L2Cache, "Token protocol") + : int l2_request_latency, + int l2_response_latency, + int N_tokens, + bool filtering_enabled +{ // L2 BANK QUEUES // From local bank of L2 cache TO the network - MessageBuffer L1RequestFromL2Cache, network="To", virtual_network="0", ordered="false"; // this L2 bank -> a local L1 - MessageBuffer GlobalRequestFromL2Cache, network="To", virtual_network="1", ordered="false"; // this L2 bank -> mod-directory - MessageBuffer responseFromL2Cache, network="To", virtual_network="2", ordered="false"; // this L2 bank -> a local L1 || mod-directory + + // this L2 bank -> a local L1 || mod-directory + MessageBuffer responseFromL2Cache, network="To", virtual_network="1", ordered="false"; + // this L2 bank -> mod-directory + MessageBuffer GlobalRequestFromL2Cache, network="To", virtual_network="3", ordered="false"; + // this L2 bank -> a local L1 + MessageBuffer L1RequestFromL2Cache, network="To", virtual_network="4", ordered="false"; // FROM the network to this local bank of L2 cache - MessageBuffer L1RequestToL2Cache, network="From", virtual_network="0", ordered="false"; // a local L1 -> this L2 bank - MessageBuffer GlobalRequestToL2Cache, network="From", virtual_network="1", ordered="false"; // mod-directory -> this L2 bank - MessageBuffer responseToL2Cache, network="From", virtual_network="2", ordered="false"; // a local L1 || mod-directory -> this L2 bank - MessageBuffer persistentToL2Cache, network="From", virtual_network="3", ordered="true"; + + // a local L1 || mod-directory -> this L2 bank + MessageBuffer responseToL2Cache, network="From", virtual_network="1", ordered="false"; + MessageBuffer persistentToL2Cache, network="From", virtual_network="2", ordered="true"; + // mod-directory -> this L2 bank + MessageBuffer GlobalRequestToL2Cache, network="From", virtual_network="3", ordered="false"; + // a local L1 -> this L2 bank + MessageBuffer L1RequestToL2Cache, network="From", virtual_network="4", ordered="false"; // STATES enumeration(State, desc="L2 Cache states", default="L2Cache_State_I") { @@ -107,8 +120,6 @@ machine(L2Cache, "Token protocol") { DataBlock DataBlk, desc="data for the block"; } - - structure(DirEntry, desc="...") { Set Sharers, desc="Set of the internal processors that want the block in shared state"; bool exclusive, default="false", desc="if local exclusive is likely"; @@ -117,7 +128,7 @@ machine(L2Cache, "Token protocol") { external_type(CacheMemory) { bool cacheAvail(Address); Address cacheProbe(Address); - void allocate(Address); + void allocate(Address, Entry); void deallocate(Address); Entry lookup(Address); void changePermission(Address, AccessPermission); @@ -132,19 +143,28 @@ machine(L2Cache, "Token protocol") { bool isTagPresent(Address); } + external_type(PersistentTable) { + void persistentRequestLock(Address, MachineID, AccessType); + void persistentRequestUnlock(Address, MachineID); + MachineID findSmallest(Address); + AccessType typeOfSmallest(Address); + void markEntries(Address); + bool isLocked(Address); + int countStarvingForAddress(Address); + int countReadStarvingForAddress(Address); + } - CacheMemory L2cacheMemory, template_hack="<L2Cache_Entry>", constructor_hack='L2_CACHE_NUM_SETS_BITS,L2_CACHE_ASSOC,MachineType_L2Cache,int_to_string(i)+"_L2"'; + CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["cache"])'; - PersistentTable persistentTable, constructor_hack="i"; + PersistentTable persistentTable; PerfectCacheMemory localDirectory, template_hack="<L2Cache_DirEntry>"; - - bool getFilteringEnabled(); - Entry getL2CacheEntry(Address addr), return_by_ref="yes" { if (L2cacheMemory.isTagPresent(addr)) { return L2cacheMemory[addr]; } + assert(false); + return L2cacheMemory[addr]; } int getTokens(Address addr) { @@ -465,15 +485,21 @@ machine(L2Cache, "Token protocol") { // if this is a retry or no local sharers, broadcast normally // if (in_msg.RetryNum > 0 || (in_msg.Type == CoherenceRequestType:GETX && exclusiveExists(in_msg.Address) == false) || (in_msg.Type == CoherenceRequestType:GETS && sharersExist(in_msg.Address) == false)) { - enqueue(globalRequestNetwork_out, RequestMsg, latency="L2_REQUEST_LATENCY") { + enqueue(globalRequestNetwork_out, RequestMsg, latency=l2_request_latency) { out_msg.Address := in_msg.Address; out_msg.Type := in_msg.Type; out_msg.Requestor := in_msg.Requestor; out_msg.RequestorMachine := in_msg.RequestorMachine; - //out_msg.Destination.broadcast(MachineType:L2Cache); out_msg.RetryNum := in_msg.RetryNum; - out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); - out_msg.Destination.remove(map_L1CacheMachId_to_L2Cache(address, in_msg.Requestor)); + + // + // If a statically shared L2 cache, then no other L2 caches can + // store the block + // + //out_msg.Destination.broadcast(MachineType:L2Cache); + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + //out_msg.Destination.remove(map_L1CacheMachId_to_L2Cache(address, in_msg.Requestor)); + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.AccessMode := in_msg.AccessMode; @@ -489,7 +515,7 @@ machine(L2Cache, "Token protocol") { action(bb_bounceResponse, "\b", desc="Bounce tokens and data to memory") { peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -505,7 +531,7 @@ machine(L2Cache, "Token protocol") { action(c_cleanReplacement, "c", desc="Issue clean writeback") { if (getL2CacheEntry(address).Tokens > 0) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -519,7 +545,7 @@ machine(L2Cache, "Token protocol") { } action(cc_dirtyReplacement, "\c", desc="Issue dirty writeback") { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; @@ -541,22 +567,22 @@ machine(L2Cache, "Token protocol") { action(d_sendDataWithTokens, "d", desc="Send data and a token from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - if (getL2CacheEntry(address).Tokens > N_tokens()) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + if (getL2CacheEntry(address).Tokens > N_tokens) { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; out_msg.Destination.add(in_msg.Requestor); - out_msg.Tokens := N_tokens(); + out_msg.Tokens := N_tokens; out_msg.DataBlk := getL2CacheEntry(address).DataBlk; out_msg.Dirty := false; out_msg.MessageSize := MessageSizeType:Response_Data; } - getL2CacheEntry(address).Tokens := getL2CacheEntry(address).Tokens - N_tokens(); + getL2CacheEntry(address).Tokens := getL2CacheEntry(address).Tokens - N_tokens; } else { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; @@ -574,7 +600,7 @@ machine(L2Cache, "Token protocol") { action(dd_sendDataWithAllTokens, "\d", desc="Send data and all tokens from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -592,7 +618,7 @@ machine(L2Cache, "Token protocol") { action(e_sendAckWithCollectedTokens, "e", desc="Send ack with the tokens we've collected thus far.") { if (getL2CacheEntry(address).Tokens > 0) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -607,7 +633,7 @@ machine(L2Cache, "Token protocol") { } action(ee_sendDataWithAllTokens, "\e", desc="Send data and all tokens from cache to starver") { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -626,7 +652,7 @@ machine(L2Cache, "Token protocol") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getL2CacheEntry(address).Tokens > 0); if (getL2CacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -644,7 +670,7 @@ machine(L2Cache, "Token protocol") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getL2CacheEntry(address).Tokens > 0); if (getL2CacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -666,7 +692,7 @@ machine(L2Cache, "Token protocol") { // assert(persistentTable.isLocked(address)); peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet in some cases - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -684,7 +710,7 @@ machine(L2Cache, "Token protocol") { //assert(persistentTable.isLocked(address)); peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet in some cases - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; if (in_msg.Type == CoherenceResponseType:WB_SHARED_DATA) { out_msg.Type := CoherenceResponseType:DATA_SHARED; @@ -706,7 +732,7 @@ machine(L2Cache, "Token protocol") { // assert(persistentTable.isLocked(address)); peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet in some cases - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -729,24 +755,31 @@ machine(L2Cache, "Token protocol") { action(j_forwardTransientRequestToLocalSharers, "j", desc="Forward external transient request to local sharers") { peek(requestNetwork_in, RequestMsg) { - if (getFilteringEnabled() == true && in_msg.RetryNum == 0 && sharersExist(in_msg.Address) == false) { - profile_filter_action(1); + if (filtering_enabled == true && in_msg.RetryNum == 0 && sharersExist(in_msg.Address) == false) { + //profile_filter_action(1); DEBUG_EXPR("filtered message"); DEBUG_EXPR(in_msg.RetryNum); } else { - enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) { + enqueue(localRequestNetwork_out, RequestMsg, latency=l2_response_latency ) { out_msg.Address := in_msg.Address; out_msg.Requestor := in_msg.Requestor; out_msg.RequestorMachine := in_msg.RequestorMachine; - out_msg.Destination := getLocalL1IDs(machineID); + + // + // Currently assuming only one chip so all L1s are local + // + //out_msg.Destination := getLocalL1IDs(machineID); + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.remove(in_msg.Requestor); + out_msg.Type := in_msg.Type; out_msg.isLocal := false; out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.AccessMode := in_msg.AccessMode; out_msg.Prefetch := in_msg.Prefetch; } - profile_filter_action(0); + //profile_filter_action(0); } } } @@ -756,7 +789,7 @@ machine(L2Cache, "Token protocol") { peek(L1requestNetwork_in, RequestMsg) { assert(getL2CacheEntry(address).Tokens > 0); //enqueue(responseIntraChipL2Network_out, ResponseMsg, latency="L2_to_L1_RESPONSE_LATENCY") { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; @@ -774,7 +807,7 @@ machine(L2Cache, "Token protocol") { action(k_dataOwnerFromL2CacheToL1Requestor, "\k", desc="Send data and a token from cache to L1 requestor") { peek(L1requestNetwork_in, RequestMsg) { assert(getL2CacheEntry(address).Tokens > 0); - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -793,7 +826,7 @@ machine(L2Cache, "Token protocol") { peek(L1requestNetwork_in, RequestMsg) { // assert(getL2CacheEntry(address).Tokens == max_tokens()); //enqueue(responseIntraChipL2Network_out, ResponseMsg, latency="L2_to_L1_RESPONSE_LATENCY") { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -840,12 +873,13 @@ machine(L2Cache, "Token protocol") { } action(r_markNewSharer, "r", desc="Mark the new local sharer from local request message") { - peek(L1requestNetwork_in, RequestMsg) { - if (in_msg.Type == CoherenceRequestType:GETX) { - setNewWriter(in_msg.Address, machineIDToNodeID(in_msg.Requestor)); - } else if (in_msg.Type == CoherenceRequestType:GETS) { - addNewSharer(in_msg.Address, machineIDToNodeID(in_msg.Requestor)); + if (machineIDToMachineType(in_msg.Requestor) == MachineType:L1Cache) { + if (in_msg.Type == CoherenceRequestType:GETX) { + setNewWriter(in_msg.Address, machineIDToNodeID(in_msg.Requestor)); + } else if (in_msg.Type == CoherenceRequestType:GETS) { + addNewSharer(in_msg.Address, machineIDToNodeID(in_msg.Requestor)); + } } } } @@ -854,16 +888,19 @@ machine(L2Cache, "Token protocol") { clearExclusiveBitIfExists(address); } - action( r_setMRU, "\rr", desc="manually set the MRU bit for cache line" ) { - if(isCacheTagPresent(address)) { - L2cacheMemory.setMRU(address); + action(r_setMRU, "\rr", desc="manually set the MRU bit for cache line" ) { + peek(L1requestNetwork_in, RequestMsg) { + if ((machineIDToMachineType(in_msg.Requestor) == MachineType:L1Cache) && + (isCacheTagPresent(address))) { + L2cacheMemory.setMRU(address); + } } } action(t_sendAckWithCollectedTokens, "t", desc="Send ack with the tokens we've collected thus far.") { if (getL2CacheEntry(address).Tokens > 0) { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -881,7 +918,7 @@ machine(L2Cache, "Token protocol") { action(tt_sendLocalAckWithCollectedTokens, "tt", desc="Send ack with the tokens we've collected thus far.") { if (getL2CacheEntry(address).Tokens > 0) { peek(L1requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -906,19 +943,19 @@ machine(L2Cache, "Token protocol") { } action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") { - L2cacheMemory.allocate(address); + L2cacheMemory.allocate(address, new Entry); } action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") { L2cacheMemory.deallocate(address); } - action(uu_profileMiss, "\u", desc="Profile the demand miss") { - peek(L1requestNetwork_in, RequestMsg) { + //action(uu_profileMiss, "\u", desc="Profile the demand miss") { + // peek(L1requestNetwork_in, RequestMsg) { // AccessModeType not implemented //profile_L2Cache_miss(convertToGenericType(in_msg.Type), in_msg.AccessMode, MessageSizeTypeToInt(in_msg.MessageSize), in_msg.Prefetch, machineIDToNodeID(in_msg.Requestor)); - } - } + // } + //} action(w_assertIncomingDataAndCacheDataMatch, "w", desc="Assert that the incoming data and the data in the cache match") { @@ -927,11 +964,6 @@ machine(L2Cache, "Token protocol") { } } - action(z_stall, "z", desc="Stall") { - } - - - //***************************************************** // TRANSITIONS @@ -961,7 +993,7 @@ machine(L2Cache, "Token protocol") { transition(NP, {L1_GETS, L1_GETX}) { a_broadcastLocalRequest; r_markNewSharer; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1012,7 +1044,7 @@ machine(L2Cache, "Token protocol") { a_broadcastLocalRequest; tt_sendLocalAckWithCollectedTokens; // send any tokens we have collected r_markNewSharer; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1020,7 +1052,7 @@ machine(L2Cache, "Token protocol") { a_broadcastLocalRequest; tt_sendLocalAckWithCollectedTokens; // send any tokens we have collected r_markNewSharer; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1181,7 +1213,7 @@ machine(L2Cache, "Token protocol") { tt_sendLocalAckWithCollectedTokens; r_markNewSharer; r_setMRU; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1294,7 +1326,7 @@ machine(L2Cache, "Token protocol") { k_dataAndAllTokensFromL2CacheToL1Requestor; r_markNewSharer; r_setMRU; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1382,7 +1414,7 @@ machine(L2Cache, "Token protocol") { transition(I_L, {L1_GETX, L1_GETS}) { a_broadcastLocalRequest; r_markNewSharer; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1391,7 +1423,7 @@ machine(L2Cache, "Token protocol") { tt_sendLocalAckWithCollectedTokens; r_markNewSharer; r_setMRU; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm index 1592fd123..7925a8fe0 100644 --- a/src/mem/protocol/MOESI_CMP_token-dir.sm +++ b/src/mem/protocol/MOESI_CMP_token-dir.sm @@ -32,14 +32,23 @@ */ -machine(Directory, "Token protocol") { - - MessageBuffer requestFromDir, network="To", virtual_network="1", ordered="false"; - MessageBuffer responseFromDir, network="To", virtual_network="2", ordered="false"; - - MessageBuffer persistentToDir, network="From", virtual_network="3", ordered="true"; - MessageBuffer requestToDir, network="From", virtual_network="1", ordered="false"; - MessageBuffer responseToDir, network="From", virtual_network="2", ordered="false"; +machine(Directory, "Token protocol") + : int directory_latency, + int l2_select_low_bit, + int l2_select_num_bits, + bool distributed_persistent, + int fixed_timeout_latency +{ + + MessageBuffer dmaResponseFromDir, network="To", virtual_network="0", ordered="true"; + MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false"; + MessageBuffer persistentFromDir, network="To", virtual_network="2", ordered="true"; + MessageBuffer requestFromDir, network="To", virtual_network="4", ordered="false"; + + MessageBuffer responseToDir, network="From", virtual_network="1", ordered="false"; + MessageBuffer persistentToDir, network="From", virtual_network="2", ordered="true"; + MessageBuffer requestToDir, network="From", virtual_network="3", ordered="false"; + MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true"; // STATES enumeration(State, desc="Directory states", default="Directory_State_O") { @@ -47,6 +56,24 @@ machine(Directory, "Token protocol") { O, desc="Owner"; NO, desc="Not Owner"; L, desc="Locked"; + + // Memory wait states - can block all messages including persistent requests + O_W, desc="transitioning to Owner, waiting for memory write"; + L_W, desc="transitioning to Locked, waiting for memory read"; + DR_L_W, desc="transitioning to Locked underneath a DMA read, waiting for memory data"; + NO_W, desc="transitioning to Not Owner, waiting for memory read"; + O_DW_W, desc="transitioning to Owner, waiting for memory before DMA ack"; + O_DR_W, desc="transitioning to Owner, waiting for memory before DMA data"; + + // DMA request transient states - must respond to persistent requests + O_DW, desc="issued GETX for DMA write, waiting for all tokens"; + NO_DW, desc="issued GETX for DMA write, waiting for all tokens"; + NO_DR, desc="issued GETS for DMA read, waiting for data"; + + // DMA request in progress - competing with a CPU persistent request + DW_L, desc="issued GETX for DMA write, CPU persistent request must complete first"; + DR_L, desc="issued GETS for DMA read, CPU persistent request must complete first"; + } // Events @@ -55,9 +82,23 @@ machine(Directory, "Token protocol") { GETS, desc="A GETS arrives"; Lockdown, desc="A lockdown request arrives"; Unlockdown, desc="An un-lockdown request arrives"; + Own_Lock_or_Unlock, desc="own lock or unlock"; Data_Owner, desc="Data arrive"; + Data_All_Tokens, desc="Data and all tokens"; Ack_Owner, desc="Owner token arrived without data because it was clean"; + Ack_Owner_All_Tokens, desc="All tokens including owner arrived without data because it was clean"; Tokens, desc="Tokens arrive"; + Ack_All_Tokens, desc="All_Tokens arrive"; + Request_Timeout, desc="A DMA request has timed out"; + + // Memory Controller + Memory_Data, desc="Fetched data from memory arrives"; + Memory_Ack, desc="Writeback Ack from memory arrives"; + + // DMA requests + DMA_READ, desc="A DMA Read memory request"; + DMA_WRITE, desc="A DMA Write memory request"; + DMA_WRITE_All_Tokens, desc="A DMA Write memory request, directory has all tokens"; } // TYPES @@ -73,7 +114,7 @@ machine(Directory, "Token protocol") { // is 'soft state' that does not need to be correct (as long as // you're eventually willing to resort to broadcast.) - Set Owner, desc="Probable Owner of the line. More accurately, the set of processors who need to see a GetS or GetO. We use a Set for convenience, but only one bit is set at a time."; + Set Owner, desc="Probable Owner of the line. More accurately, the set of processors who need to see a GetS or GetO. We use a Set for convenience, but only one bit is set at a time."; Set Sharers, desc="Probable sharers of the line. More accurately, the set of processors who need to see a GetX"; } @@ -82,23 +123,70 @@ machine(Directory, "Token protocol") { bool isPresent(Address); } + external_type(MemoryControl, inport="yes", outport="yes") { + + } + + external_type(PersistentTable) { + void persistentRequestLock(Address, MachineID, AccessType); + void persistentRequestUnlock(Address, MachineID); + bool okToIssueStarving(Address, MachineID); + MachineID findSmallest(Address); + AccessType typeOfSmallest(Address); + void markEntries(Address); + bool isLocked(Address); + int countStarvingForAddress(Address); + int countReadStarvingForAddress(Address); + } + + // TBE entries for DMA requests + structure(TBE, desc="TBE entries for outstanding DMA requests") { + Address PhysicalAddress, desc="physical address"; + State TBEState, desc="Transient State"; + DataBlock DmaDataBlk, desc="DMA Data to be written. Partial blocks need to merged with system memory"; + DataBlock DataBlk, desc="The current view of system memory"; + int Len, desc="..."; + MachineID DmaRequestor, desc="DMA requestor"; + bool WentPersistent, desc="Did the DMA request require a persistent request"; + } + + external_type(TBETable) { + TBE lookup(Address); + void allocate(Address); + void deallocate(Address); + bool isPresent(Address); + } // ** OBJECTS ** - DirectoryMemory directory, constructor_hack="i"; + DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])'; + + MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])'; - PersistentTable persistentTable, constructor_hack="i"; + PersistentTable persistentTable; + TimerTable reissueTimerTable; + + TBETable TBEs, template_hack="<Directory_TBE>"; + + bool starving, default="false"; State getState(Address addr) { - return directory[addr].DirectoryState; + if (TBEs.isPresent(addr)) { + return TBEs[addr].TBEState; + } else { + return directory[addr].DirectoryState; + } } void setState(Address addr, State state) { + if (TBEs.isPresent(addr)) { + TBEs[addr].TBEState := state; + } directory[addr].DirectoryState := state; if (state == State:L) { assert(directory[addr].Tokens == 0); - } + } // We have one or zero owners assert((directory[addr].Owner.count() == 0) || (directory[addr].Owner.count() == 1)); @@ -112,19 +200,90 @@ machine(Directory, "Token protocol") { // assert(directory[addr].Tokens >= (max_tokens() / 2)); // Only mostly true; this might not always hold } } + + bool okToIssueStarving(Address addr, MachineID machinID) { + return persistentTable.okToIssueStarving(addr, machineID); + } + + void markPersistentEntries(Address addr) { + persistentTable.markEntries(addr); + } // ** OUT_PORTS ** out_port(responseNetwork_out, ResponseMsg, responseFromDir); + out_port(persistentNetwork_out, PersistentMsg, persistentFromDir); out_port(requestNetwork_out, RequestMsg, requestFromDir); + out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir); + + // + // Memory buffer for memory controller to DIMM communication + // + out_port(memQueue_out, MemoryMsg, memBuffer); // ** IN_PORTS ** + + // off-chip memory request/response is done + in_port(memQueue_in, MemoryMsg, memBuffer) { + if (memQueue_in.isReady()) { + peek(memQueue_in, MemoryMsg) { + if (in_msg.Type == MemoryRequestType:MEMORY_READ) { + trigger(Event:Memory_Data, in_msg.Address); + } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) { + trigger(Event:Memory_Ack, in_msg.Address); + } else { + DEBUG_EXPR(in_msg.Type); + error("Invalid message"); + } + } + } + } + + // Reissue Timer + in_port(reissueTimerTable_in, Address, reissueTimerTable) { + if (reissueTimerTable_in.isReady()) { + trigger(Event:Request_Timeout, reissueTimerTable.readyAddress()); + } + } + + in_port(responseNetwork_in, ResponseMsg, responseToDir) { + if (responseNetwork_in.isReady()) { + peek(responseNetwork_in, ResponseMsg) { + assert(in_msg.Destination.isElement(machineID)); + if (directory[in_msg.Address].Tokens + in_msg.Tokens == max_tokens()) { + if ((in_msg.Type == CoherenceResponseType:DATA_OWNER) || + (in_msg.Type == CoherenceResponseType:DATA_SHARED)) { + trigger(Event:Data_All_Tokens, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) { + trigger(Event:Ack_Owner_All_Tokens, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK) { + trigger(Event:Ack_All_Tokens, in_msg.Address); + } else { + DEBUG_EXPR(in_msg.Type); + error("Invalid message"); + } + } else { + if (in_msg.Type == CoherenceResponseType:DATA_OWNER) { + trigger(Event:Data_Owner, in_msg.Address); + } else if ((in_msg.Type == CoherenceResponseType:ACK) || + (in_msg.Type == CoherenceResponseType:DATA_SHARED)) { + trigger(Event:Tokens, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) { + trigger(Event:Ack_Owner, in_msg.Address); + } else { + DEBUG_EXPR(in_msg.Type); + error("Invalid message"); + } + } + } + } + } in_port(persistentNetwork_in, PersistentMsg, persistentToDir) { if (persistentNetwork_in.isReady()) { peek(persistentNetwork_in, PersistentMsg) { assert(in_msg.Destination.isElement(machineID)); - if (distributedPersistentEnabled()) { + if (distributed_persistent) { // Apply the lockdown or unlockdown message to the table if (in_msg.Type == PersistentRequestType:GETX_PERSISTENT) { persistentTable.persistentRequestLock(in_msg.Address, in_msg.Requestor, AccessType:Write); @@ -173,19 +332,18 @@ machine(Directory, "Token protocol") { } } - in_port(responseNetwork_in, ResponseMsg, responseToDir) { - if (responseNetwork_in.isReady()) { - peek(responseNetwork_in, ResponseMsg) { - assert(in_msg.Destination.isElement(machineID)); - if (in_msg.Type == CoherenceResponseType:DATA_OWNER) { - trigger(Event:Data_Owner, in_msg.Address); - } else if ((in_msg.Type == CoherenceResponseType:ACK) || - (in_msg.Type == CoherenceResponseType:DATA_SHARED)) { - trigger(Event:Tokens, in_msg.Address); - } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) { - trigger(Event:Ack_Owner, in_msg.Address); + in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) { + if (dmaRequestQueue_in.isReady()) { + peek(dmaRequestQueue_in, DMARequestMsg) { + if (in_msg.Type == DMARequestType:READ) { + trigger(Event:DMA_READ, in_msg.LineAddress); + } else if (in_msg.Type == DMARequestType:WRITE) { + if (directory[in_msg.LineAddress].Tokens == max_tokens()) { + trigger(Event:DMA_WRITE_All_Tokens, in_msg.LineAddress); + } else { + trigger(Event:DMA_WRITE, in_msg.LineAddress); + } } else { - DEBUG_EXPR(in_msg.Type); error("Invalid message"); } } @@ -199,7 +357,7 @@ machine(Directory, "Token protocol") { if (directory[address].Tokens > 0) { peek(requestNetwork_in, RequestMsg) { // enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_CACHE_LATENCY") {// FIXME? - enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_LATENCY") {// FIXME? + enqueue(responseNetwork_out, ResponseMsg, latency=directory_latency) {// FIXME? out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -213,11 +371,151 @@ machine(Directory, "Token protocol") { } } + action(px_tryIssuingPersistentGETXRequest, "px", desc="...") { + if (okToIssueStarving(address, machineID) && (starving == false)) { + enqueue(persistentNetwork_out, PersistentMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := PersistentRequestType:GETX_PERSISTENT; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + out_msg.Destination.broadcast(MachineType:L1Cache); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Persistent_Control; + out_msg.Prefetch := PrefetchBit:No; + out_msg.AccessMode := AccessModeType:SupervisorMode; + } + markPersistentEntries(address); + starving := true; + + TBEs[address].WentPersistent := true; + + // Do not schedule a wakeup, a persistent requests will always complete + } else { + + // We'd like to issue a persistent request, but are not allowed + // to issue a P.R. right now. This, we do not increment the + // IssueCount. + + // Set a wakeup timer + reissueTimerTable.set(address, 10); + } + } + + action(bw_broadcastWrite, "bw", desc="Broadcast GETX if we need tokens") { + peek(dmaRequestQueue_in, DMARequestMsg) { + // + // Assser that we only send message if we don't already have all the tokens + // + assert(directory[address].Tokens != max_tokens()); + enqueue(requestNetwork_out, RequestMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETX; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + + // + // Since only one chip, assuming all L1 caches are local + // + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.RetryNum := 0; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Prefetch := PrefetchBit:No; + out_msg.AccessMode := AccessModeType:SupervisorMode; + } + } + } + + action(ps_tryIssuingPersistentGETSRequest, "ps", desc="...") { + if (okToIssueStarving(address, machineID) && (starving == false)) { + enqueue(persistentNetwork_out, PersistentMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := PersistentRequestType:GETS_PERSISTENT; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + out_msg.Destination.broadcast(MachineType:L1Cache); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Persistent_Control; + out_msg.Prefetch := PrefetchBit:No; + out_msg.AccessMode := AccessModeType:SupervisorMode; + } + markPersistentEntries(address); + starving := true; + + TBEs[address].WentPersistent := true; + + // Do not schedule a wakeup, a persistent requests will always complete + } else { + + // We'd like to issue a persistent request, but are not allowed + // to issue a P.R. right now. This, we do not increment the + // IssueCount. + + // Set a wakeup timer + reissueTimerTable.set(address, 10); + } + } + + action(br_broadcastRead, "br", desc="Broadcast GETS for data") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(requestNetwork_out, RequestMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETS; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + + // + // Since only one chip, assuming all L1 caches are local + // + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.RetryNum := 0; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Prefetch := PrefetchBit:No; + out_msg.AccessMode := AccessModeType:SupervisorMode; + } + } + } + action(aa_sendTokensToStarver, "\a", desc="Send tokens to starver") { // Only send a message if we have tokens to send if (directory[address].Tokens > 0) { // enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_CACHE_LATENCY") {// FIXME? - enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_LATENCY") {// FIXME? + enqueue(responseNetwork_out, ResponseMsg, latency=directory_latency) {// FIXME? out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -230,14 +528,14 @@ machine(Directory, "Token protocol") { } } - action(d_sendDataWithAllTokens, "d", desc="Send data and tokens to requestor") { - peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { + action(d_sendMemoryDataWithAllTokens, "d", desc="Send data and tokens to requestor") { + peek(memQueue_in, MemoryMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:Directory; - out_msg.Destination.add(in_msg.Requestor); + out_msg.Destination.add(in_msg.OriginalRequestorMachId); assert(directory[address].Tokens > 0); out_msg.Tokens := directory[in_msg.Address].Tokens; out_msg.DataBlk := directory[in_msg.Address].DataBlk; @@ -249,21 +547,140 @@ machine(Directory, "Token protocol") { } action(dd_sendDataWithAllTokensToStarver, "\d", desc="Send data and tokens to starver") { - enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { - out_msg.Address := address; - out_msg.Type := CoherenceResponseType:DATA_OWNER; - out_msg.Sender := machineID; - out_msg.SenderMachine := MachineType:Directory; - out_msg.Destination.add(persistentTable.findSmallest(address)); - assert(directory[address].Tokens > 0); - out_msg.Tokens := directory[address].Tokens; - out_msg.DataBlk := directory[address].DataBlk; - out_msg.Dirty := false; - out_msg.MessageSize := MessageSizeType:Response_Data; + peek(memQueue_in, MemoryMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA_OWNER; + out_msg.Sender := machineID; + out_msg.SenderMachine := MachineType:Directory; + out_msg.Destination.add(persistentTable.findSmallest(address)); + assert(directory[address].Tokens > 0); + out_msg.Tokens := directory[address].Tokens; + out_msg.DataBlk := directory[address].DataBlk; + out_msg.Dirty := false; + out_msg.MessageSize := MessageSizeType:Response_Data; + } } directory[address].Tokens := 0; } + action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { + peek(requestNetwork_in, RequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := in_msg.Requestor; + out_msg.MessageSize := in_msg.MessageSize; + out_msg.DataBlk := directory[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + } + + action(fd_memoryDma, "fd", desc="Queue off-chip fetch request") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := in_msg.Requestor; + out_msg.MessageSize := in_msg.MessageSize; + out_msg.DataBlk := directory[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + } + + action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + DEBUG_EXPR(out_msg); + } + } + + action(ld_queueMemoryDmaWriteFromTbe, "ld", desc="Write DMA data to memory") { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + // first, initialize the data blk to the current version of system memory + out_msg.DataBlk := TBEs[address].DataBlk; + // then add the dma write data + out_msg.DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + DEBUG_EXPR(out_msg); + } + } + + action(lr_queueMemoryDmaReadWriteback, "lr", desc="Write DMA data from read to memory") { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + // first, initialize the data blk to the current version of system memory + out_msg.DataBlk := TBEs[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + + action(vd_allocateDmaRequestInTBE, "vd", desc="Record Data in TBE") { + peek(dmaRequestQueue_in, DMARequestMsg) { + TBEs.allocate(address); + TBEs[address].DmaDataBlk := in_msg.DataBlk; + TBEs[address].PhysicalAddress := in_msg.PhysicalAddress; + TBEs[address].Len := in_msg.Len; + TBEs[address].DmaRequestor := in_msg.Requestor; + TBEs[address].WentPersistent := false; + } + } + + action(s_deallocateTBE, "s", desc="Deallocate TBE") { + + if (TBEs[address].WentPersistent) { + assert(starving == true); + + enqueue(persistentNetwork_out, PersistentMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := PersistentRequestType:DEACTIVATE_PERSISTENT; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + out_msg.Destination.broadcast(MachineType:L1Cache); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Persistent_Control; + } + starving := false; + } + + TBEs.deallocate(address); + } + + action(rd_recordDataInTbe, "rd", desc="Record data in TBE") { + peek(responseNetwork_in, ResponseMsg) { + TBEs[address].DataBlk := in_msg.DataBlk; + } + } + + action(cd_writeCleanDataToTbe, "cd", desc="Write clean memory data to TBE") { + TBEs[address].DataBlk := directory[address].DataBlk; + } + + action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") { + directory[address].DataBlk := TBEs[address].DataBlk; + directory[address].DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + } + action(f_incrementTokens, "f", desc="Increment the number of tokens we're tracking") { peek(responseNetwork_in, ResponseMsg) { assert(in_msg.Tokens >= 1); @@ -275,14 +692,34 @@ machine(Directory, "Token protocol") { requestNetwork_in.dequeue(); } + action(z_recycleRequest, "z", desc="Recycle the request queue") { + requestNetwork_in.recycle(); + } + action(k_popIncomingResponseQueue, "k", desc="Pop incoming response queue") { responseNetwork_in.dequeue(); } + action(kz_recycleResponse, "kz", desc="Recycle incoming response queue") { + responseNetwork_in.recycle(); + } + action(l_popIncomingPersistentQueue, "l", desc="Pop incoming persistent queue") { persistentNetwork_in.dequeue(); } + action(p_popDmaRequestQueue, "pd", desc="pop dma request queue") { + dmaRequestQueue_in.dequeue(); + } + + action(y_recycleDmaRequestQueue, "y", desc="recycle dma request queue") { + dmaRequestQueue_in.recycle(); + } + + action(l_popMemQueue, "q", desc="Pop off-chip request queue") { + memQueue_in.dequeue(); + } + action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") { peek(responseNetwork_in, ResponseMsg) { directory[in_msg.Address].DataBlk := in_msg.DataBlk; @@ -291,18 +728,15 @@ machine(Directory, "Token protocol") { } } - action(n_checkIncomingMsg, "n", desc="Check incoming token message") { + action(n_checkData, "n", desc="Check incoming clean data message") { peek(responseNetwork_in, ResponseMsg) { - assert(in_msg.Type == CoherenceResponseType:ACK_OWNER); - assert(in_msg.Dirty == false); - assert(in_msg.MessageSize == MessageSizeType:Writeback_Control); assert(directory[in_msg.Address].DataBlk == in_msg.DataBlk); } } action(r_bounceResponse, "r", desc="Bounce response to starving processor") { peek(responseNetwork_in, ResponseMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -316,7 +750,20 @@ machine(Directory, "Token protocol") { } } - action(s_bounceDatalessOwnerToken, "s", desc="Bounce clean owner token to starving processor") { + action(st_scheduleTimeout, "st", desc="Schedule Timeout") { + // + // currently only support a fixed timeout latency + // + reissueTimerTable.set(address, fixed_timeout_latency); + } + + action(ut_unsetReissueTimer, "ut", desc="Unset reissue timer.") { + if (reissueTimerTable.isSet(address)) { + reissueTimerTable.unset(address); + } + } + + action(bd_bounceDatalessOwnerToken, "bd", desc="Bounce clean owner token to starving processor") { peek(responseNetwork_in, ResponseMsg) { assert(in_msg.Type == CoherenceResponseType:ACK_OWNER); assert(in_msg.Dirty == false); @@ -331,7 +778,7 @@ machine(Directory, "Token protocol") { // Bounce the message, but "re-associate" the data and the owner // token. In essence we're converting an ACK_OWNER message to a // DATA_OWNER message, keeping the number of tokens the same. - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -346,53 +793,212 @@ machine(Directory, "Token protocol") { } } + action(da_sendDmaAck, "da", desc="Send Ack to DMA controller") { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:ACK; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + + action(dm_sendMemoryDataToDma, "dm", desc="Send Data to DMA controller from memory") { + peek(memQueue_in, MemoryMsg) { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:DATA; + // + // we send the entire data block and rely on the dma controller to + // split it up if need be + // + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(dd_sendDmaData, "dd", desc="Send Data to DMA controller") { + peek(responseNetwork_in, ResponseMsg) { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:DATA; + // + // we send the entire data block and rely on the dma controller to + // split it up if need be + // + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } // TRANSITIONS - // Trans. from O - transition(O, GETX, NO) { - d_sendDataWithAllTokens; + // + // Trans. from base state O + // the directory has valid data + // + transition(O, GETX, NO_W) { + qf_queueMemoryFetchRequest; j_popIncomingRequestQueue; } - transition(O, GETS, NO) { - d_sendDataWithAllTokens; + transition(O, DMA_WRITE, O_DW) { + vd_allocateDmaRequestInTBE; + bw_broadcastWrite; + st_scheduleTimeout; + p_popDmaRequestQueue; + } + + transition(O, DMA_WRITE_All_Tokens, O_DW_W) { + vd_allocateDmaRequestInTBE; + cd_writeCleanDataToTbe; + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWriteFromTbe; + p_popDmaRequestQueue; + } + + transition(O, GETS, NO_W) { + qf_queueMemoryFetchRequest; j_popIncomingRequestQueue; } - transition(O, Lockdown, L) { - dd_sendDataWithAllTokensToStarver; + transition(O, DMA_READ, O_DR_W) { + vd_allocateDmaRequestInTBE; + fd_memoryDma; + st_scheduleTimeout; + p_popDmaRequestQueue; + } + + transition(O, Lockdown, L_W) { + qf_queueMemoryFetchRequest; + l_popIncomingPersistentQueue; + } + + transition(O, {Tokens, Ack_All_Tokens}) { + f_incrementTokens; + k_popIncomingResponseQueue; + } + + transition(O, {Data_Owner, Data_All_Tokens}) { + n_checkData; + f_incrementTokens; + k_popIncomingResponseQueue; + } + + // + // transitioning to Owner, waiting for memory before DMA ack + // All other events should recycle/stall + // + transition(O_DR_W, Memory_Data, O) { + dm_sendMemoryDataToDma; + ut_unsetReissueTimer; + s_deallocateTBE; + l_popMemQueue; + } + + // + // issued GETX for DMA write, waiting for all tokens + // + transition(O_DW, Tokens) { + f_incrementTokens; + k_popIncomingResponseQueue; + } + + transition(O_DW, Data_Owner) { + f_incrementTokens; + rd_recordDataInTbe; + k_popIncomingResponseQueue; + } + + transition(O_DW, Ack_Owner) { + f_incrementTokens; + cd_writeCleanDataToTbe; + k_popIncomingResponseQueue; + } + + transition(O_DW, Lockdown, DW_L) { l_popIncomingPersistentQueue; } - transition(O, Tokens) { + transition({NO_DW, O_DW}, Data_All_Tokens, O_DW_W) { f_incrementTokens; + rd_recordDataInTbe; + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWriteFromTbe; + ut_unsetReissueTimer; k_popIncomingResponseQueue; } + transition(O_DW, Ack_All_Tokens, O_DW_W) { + f_incrementTokens; + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWriteFromTbe; + ut_unsetReissueTimer; + k_popIncomingResponseQueue; + } + + transition(O_DW, Ack_Owner_All_Tokens, O_DW_W) { + f_incrementTokens; + cd_writeCleanDataToTbe; + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWriteFromTbe; + ut_unsetReissueTimer; + k_popIncomingResponseQueue; + } + + transition(O_DW_W, Memory_Ack, O) { + da_sendDmaAck; + s_deallocateTBE; + l_popMemQueue; + } + + // // Trans. from NO + // The direcotry does not have valid data, but may have some tokens + // transition(NO, GETX) { a_sendTokens; j_popIncomingRequestQueue; } + transition(NO, DMA_WRITE, NO_DW) { + vd_allocateDmaRequestInTBE; + bw_broadcastWrite; + st_scheduleTimeout; + p_popDmaRequestQueue; + } + transition(NO, GETS) { j_popIncomingRequestQueue; } + transition(NO, DMA_READ, NO_DR) { + vd_allocateDmaRequestInTBE; + br_broadcastRead; + st_scheduleTimeout; + p_popDmaRequestQueue; + } + transition(NO, Lockdown, L) { aa_sendTokensToStarver; l_popIncomingPersistentQueue; } - transition(NO, Data_Owner, O) { + transition(NO, {Data_Owner, Data_All_Tokens}, O_W) { m_writeDataToMemory; f_incrementTokens; + lq_queueMemoryWbRequest; k_popIncomingResponseQueue; } - transition(NO, Ack_Owner, O) { - n_checkIncomingMsg; + transition(NO, {Ack_Owner, Ack_Owner_All_Tokens}, O) { + n_checkData; f_incrementTokens; k_popIncomingResponseQueue; } @@ -402,34 +1008,156 @@ machine(Directory, "Token protocol") { k_popIncomingResponseQueue; } + transition(NO_W, Memory_Data, NO) { + d_sendMemoryDataWithAllTokens; + l_popMemQueue; + } + + // Trans. from NO_DW + transition(NO_DW, Request_Timeout) { + ut_unsetReissueTimer; + px_tryIssuingPersistentGETXRequest; + } + + transition(NO_DW, Lockdown, DW_L) { + aa_sendTokensToStarver; + l_popIncomingPersistentQueue; + } + + // Note: NO_DW, Data_All_Tokens transition is combined with O_DW + // Note: NO_DW should not receive the action Ack_All_Tokens because the + // directory does not have valid data + + transition(NO_DW, Data_Owner, O_DW) { + f_incrementTokens; + rd_recordDataInTbe; + lq_queueMemoryWbRequest; + k_popIncomingResponseQueue; + } + + transition({NO_DW, NO_DR}, Tokens) { + f_incrementTokens; + k_popIncomingResponseQueue; + } + + // Trans. from NO_DR + transition(NO_DR, Request_Timeout) { + ut_unsetReissueTimer; + ps_tryIssuingPersistentGETSRequest; + } + + transition(NO_DR, Lockdown, DR_L) { + aa_sendTokensToStarver; + l_popIncomingPersistentQueue; + } + + transition(NO_DR, {Data_Owner, Data_All_Tokens}, O_W) { + m_writeDataToMemory; + f_incrementTokens; + dd_sendDmaData; + lr_queueMemoryDmaReadWriteback; + ut_unsetReissueTimer; + s_deallocateTBE; + k_popIncomingResponseQueue; + } + // Trans. from L - transition(L, {GETX, GETS}) { + transition({L, DW_L, DR_L}, {GETX, GETS}) { j_popIncomingRequestQueue; } - transition(L, Lockdown) { + transition({L, DW_L, DR_L, L_W, DR_L_W}, Lockdown) { l_popIncomingPersistentQueue; } - // we could change this to write the data to memory and send it cleanly - transition(L, Data_Owner) { + // + // Received data for lockdown blocks + // For blocks with outstanding dma requests to them + // ...we could change this to write the data to memory and send it cleanly + // ...we could also proactively complete our DMA requests + // However, to keep my mind from spinning out-of-control, we won't for now :) + // + transition({DW_L, DR_L, L}, {Data_Owner, Data_All_Tokens}) { r_bounceResponse; k_popIncomingResponseQueue; } - transition(L, Tokens) { + transition({DW_L, DR_L, L}, Tokens) { r_bounceResponse; k_popIncomingResponseQueue; } - transition(L, Ack_Owner) { - s_bounceDatalessOwnerToken; + transition({DW_L, DR_L, L}, {Ack_Owner_All_Tokens, Ack_Owner}) { + bd_bounceDatalessOwnerToken; k_popIncomingResponseQueue; } - transition(L, Unlockdown, NO) { l_popIncomingPersistentQueue; } + transition(L_W, Memory_Data, L) { + dd_sendDataWithAllTokensToStarver; + l_popMemQueue; + } + + transition(DR_L_W, Memory_Data, DR_L) { + dd_sendDataWithAllTokensToStarver; + l_popMemQueue; + } + + transition(DW_L, {Unlockdown, Own_Lock_or_Unlock}, NO_DW) { + l_popIncomingPersistentQueue; + } + + transition(DR_L_W, {Unlockdown, Own_Lock_or_Unlock}, O_DR_W) { + l_popIncomingPersistentQueue; + } + + transition({DW_L, DR_L_W}, Request_Timeout) { + ut_unsetReissueTimer; + px_tryIssuingPersistentGETXRequest; + } + + transition(DR_L, {Unlockdown, Own_Lock_or_Unlock}, NO_DR) { + l_popIncomingPersistentQueue; + } + + transition(DR_L, Request_Timeout) { + ut_unsetReissueTimer; + ps_tryIssuingPersistentGETSRequest; + } + + transition(O_W, Memory_Ack, O) { + l_popMemQueue; + } + + transition({O, NO, L, O_DW, NO_DW, NO_DR}, Own_Lock_or_Unlock) { + l_popIncomingPersistentQueue; + } + + // Blocked states + transition({NO_W, O_W, L_W, DR_L_W, O_DW_W, O_DR_W, O_DW, NO_DW, NO_DR}, {GETX, GETS}) { + z_recycleRequest; + } + + transition({NO_W, O_W, L_W, DR_L_W, O_DW_W, O_DR_W, O_DW, NO_DW, NO_DR, L, DW_L, DR_L}, {DMA_READ, DMA_WRITE}) { + y_recycleDmaRequestQueue; + } + + transition({NO_W, O_W, L_W, DR_L_W, O_DW_W, O_DR_W}, {Data_Owner, Ack_Owner, Tokens}) { + kz_recycleResponse; + } + + transition({NO_W, O_W}, Lockdown, L_W) { + l_popIncomingPersistentQueue; + } + + transition(O_DR_W, Lockdown, DR_L_W) { + l_popIncomingPersistentQueue; + } + + transition({NO_W, O_W, O_DR_W}, {Unlockdown, Own_Lock_or_Unlock}) { + l_popIncomingPersistentQueue; + } } diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm new file mode 100644 index 000000000..550a36ae0 --- /dev/null +++ b/src/mem/protocol/MOESI_CMP_token-dma.sm @@ -0,0 +1,165 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +machine(DMA, "DMA Controller") +: int request_latency +{ + + MessageBuffer responseFromDir, network="From", virtual_network="0", ordered="true", no_vector="true"; + MessageBuffer reqToDirectory, network="To", virtual_network="5", ordered="false", no_vector="true"; + + enumeration(State, desc="DMA states", default="DMA_State_READY") { + READY, desc="Ready to accept a new request"; + BUSY_RD, desc="Busy: currently processing a request"; + BUSY_WR, desc="Busy: currently processing a request"; + } + + enumeration(Event, desc="DMA events") { + ReadRequest, desc="A new read request"; + WriteRequest, desc="A new write request"; + Data, desc="Data from a DMA memory read"; + Ack, desc="DMA write to memory completed"; + } + + external_type(DMASequencer) { + void ackCallback(); + void dataCallback(DataBlock); + } + + MessageBuffer mandatoryQueue, ordered="false", no_vector="true"; + DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])', no_vector="true"; + State cur_state, no_vector="true"; + + State getState(Address addr) { + return cur_state; + } + void setState(Address addr, State state) { + cur_state := state; + } + + out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="..."); + + in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") { + if (dmaRequestQueue_in.isReady()) { + peek(dmaRequestQueue_in, SequencerMsg) { + if (in_msg.Type == SequencerRequestType:LD ) { + trigger(Event:ReadRequest, in_msg.LineAddress); + } else if (in_msg.Type == SequencerRequestType:ST) { + trigger(Event:WriteRequest, in_msg.LineAddress); + } else { + error("Invalid request type"); + } + } + } + } + + in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") { + if (dmaResponseQueue_in.isReady()) { + peek( dmaResponseQueue_in, DMAResponseMsg) { + if (in_msg.Type == DMAResponseType:ACK) { + trigger(Event:Ack, in_msg.LineAddress); + } else if (in_msg.Type == DMAResponseType:DATA) { + trigger(Event:Data, in_msg.LineAddress); + } else { + error("Invalid response type"); + } + } + } + } + + action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") { + peek(dmaRequestQueue_in, SequencerMsg) { + enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) { + out_msg.PhysicalAddress := in_msg.PhysicalAddress; + out_msg.LineAddress := in_msg.LineAddress; + out_msg.Type := DMARequestType:READ; + out_msg.Requestor := machineID; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") { + peek(dmaRequestQueue_in, SequencerMsg) { + enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) { + out_msg.PhysicalAddress := in_msg.PhysicalAddress; + out_msg.LineAddress := in_msg.LineAddress; + out_msg.Type := DMARequestType:WRITE; + out_msg.Requestor := machineID; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(a_ackCallback, "a", desc="Notify dma controller that write request completed") { + peek (dmaResponseQueue_in, DMAResponseMsg) { + dma_sequencer.ackCallback(); + } + } + + action(d_dataCallback, "d", desc="Write data to dma sequencer") { + peek (dmaResponseQueue_in, DMAResponseMsg) { + dma_sequencer.dataCallback(in_msg.DataBlk); + } + } + + action(p_popRequestQueue, "p", desc="Pop request queue") { + dmaRequestQueue_in.dequeue(); + } + + action(p_popResponseQueue, "\p", desc="Pop request queue") { + dmaResponseQueue_in.dequeue(); + } + + transition(READY, ReadRequest, BUSY_RD) { + s_sendReadRequest; + p_popRequestQueue; + } + + transition(READY, WriteRequest, BUSY_WR) { + s_sendWriteRequest; + p_popRequestQueue; + } + + transition(BUSY_RD, Data, READY) { + d_dataCallback; + p_popResponseQueue; + } + + transition(BUSY_WR, Ack, READY) { + a_ackCallback; + p_popResponseQueue; + } +} diff --git a/src/mem/protocol/MOESI_CMP_token-msg.sm b/src/mem/protocol/MOESI_CMP_token-msg.sm index 2a75ce644..40c16b5e1 100644 --- a/src/mem/protocol/MOESI_CMP_token-msg.sm +++ b/src/mem/protocol/MOESI_CMP_token-msg.sm @@ -59,8 +59,10 @@ enumeration(CoherenceResponseType, desc="...") { // TriggerType enumeration(TriggerType, desc="...") { - REQUEST_TIMEOUT, desc="See corresponding event"; + REQUEST_TIMEOUT, desc="See corresponding event"; USE_TIMEOUT, desc="See corresponding event"; + DATA, desc="data for dma read response"; + DATA_ALL_TOKENS, desc="data and all tokens for dma write response"; } // TriggerMsg @@ -111,13 +113,45 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") { MessageSizeType MessageSize, desc="size category of the message"; } -GenericRequestType convertToGenericType(CoherenceRequestType type) { - if(type == CoherenceRequestType:GETS) { - return GenericRequestType:GETS; - } else if(type == CoherenceRequestType:GETX) { - return GenericRequestType:GETX; - } else { - DEBUG_EXPR(type); - error("invalid CoherenceRequestType"); - } +enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") { + READ, desc="Memory Read"; + WRITE, desc="Memory Write"; + NULL, desc="Invalid"; } + +enumeration(DMAResponseType, desc="...", default="DMAResponseType_NULL") { + DATA, desc="DATA read"; + ACK, desc="ACK write"; + NULL, desc="Invalid"; +} + +structure(DMARequestMsg, desc="...", interface="NetworkMessage") { + DMARequestType Type, desc="Request type (read/write)"; + Address PhysicalAddress, desc="Physical address for this request"; + Address LineAddress, desc="Line address for this request"; + MachineID Requestor, desc="Node who initiated the request"; + NetDest Destination, desc="Destination"; + DataBlock DataBlk, desc="DataBlk attached to this request"; + int Len, desc="The length of the request"; + MessageSizeType MessageSize, desc="size category of the message"; +} + +structure(DMAResponseMsg, desc="...", interface="NetworkMessage") { + DMAResponseType Type, desc="Response type (DATA/ACK)"; + Address PhysicalAddress, desc="Physical address for this request"; + Address LineAddress, desc="Line address for this request"; + NetDest Destination, desc="Destination"; + DataBlock DataBlk, desc="DataBlk attached to this request"; + MessageSizeType MessageSize, desc="size category of the message"; +} + +//GenericRequestType convertToGenericType(CoherenceRequestType type) { +// if(type == CoherenceRequestType:GETS) { +// return GenericRequestType:GETS; +// } else if(type == CoherenceRequestType:GETX) { +// return GenericRequestType:GETX; +// } else { +// DEBUG_EXPR(type); +// error("invalid CoherenceRequestType"); +// } +//} diff --git a/src/mem/protocol/MOESI_CMP_token.slicc b/src/mem/protocol/MOESI_CMP_token.slicc index ae4a6d6ec..a41226f90 100644 --- a/src/mem/protocol/MOESI_CMP_token.slicc +++ b/src/mem/protocol/MOESI_CMP_token.slicc @@ -2,4 +2,5 @@ MOESI_CMP_token-msg.sm MOESI_CMP_token-L1cache.sm MOESI_CMP_token-L2cache.sm MOESI_CMP_token-dir.sm +MOESI_CMP_token-dma.sm standard_CMP-protocol.sm diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm new file mode 100644 index 000000000..3b2240800 --- /dev/null +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -0,0 +1,1132 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * AMD's contributions to the MOESI hammer protocol do not constitute an + * endorsement of its similarity to any AMD products. + * + * Authors: Milo Martin + * Brad Beckmann + */ + +machine(L1Cache, "AMD Hammer-like protocol") +: int cache_response_latency, + int issue_latency +{ + + // NETWORK BUFFERS + MessageBuffer requestFromCache, network="To", virtual_network="3", ordered="false"; + MessageBuffer responseFromCache, network="To", virtual_network="1", ordered="false"; + MessageBuffer unblockFromCache, network="To", virtual_network="0", ordered="false"; + + MessageBuffer forwardToCache, network="From", virtual_network="2", ordered="false"; + MessageBuffer responseToCache, network="From", virtual_network="1", ordered="false"; + + + // STATES + enumeration(State, desc="Cache states", default="L1Cache_State_I") { + // Base states + I, desc="Idle"; + S, desc="Shared"; + O, desc="Owned"; + M, desc="Modified (dirty)"; + MM, desc="Modified (dirty and locally modified)"; + + // Transient States + IM, "IM", desc="Issued GetX"; + SM, "SM", desc="Issued GetX, we still have an old copy of the line"; + OM, "OM", desc="Issued GetX, received data"; + ISM, "ISM", desc="Issued GetX, received data, waiting for all acks"; + M_W, "M^W", desc="Issued GetS, received exclusive data"; + MM_W, "MM^W", desc="Issued GetX, received exclusive data"; + IS, "IS", desc="Issued GetS"; + SS, "SS", desc="Issued GetS, received data, waiting for all acks"; + OI, "OI", desc="Issued PutO, waiting for ack"; + MI, "MI", desc="Issued PutX, waiting for ack"; + II, "II", desc="Issued PutX/O, saw Other_GETS or Other_GETX, waiting for ack"; + } + + // EVENTS + enumeration(Event, desc="Cache events") { + Load, desc="Load request from the processor"; + Ifetch, desc="I-fetch request from the processor"; + Store, desc="Store request from the processor"; + L2_Replacement, desc="L2 Replacement"; + L1_to_L2, desc="L1 to L2 transfer"; + L2_to_L1D, desc="L2 to L1-Data transfer"; + L2_to_L1I, desc="L2 to L1-Instruction transfer"; + + // Requests + Other_GETX, desc="A GetX from another processor"; + Other_GETS, desc="A GetS from another processor"; + + // Responses + Ack, desc="Received an ack message"; + Shared_Ack, desc="Received an ack message, responder has a shared copy"; + Data, desc="Received a data message"; + Shared_Data, desc="Received a data message, responder has a shared copy"; + Exclusive_Data, desc="Received a data message, responder had an exclusive copy, they gave it to us"; + + Writeback_Ack, desc="Writeback O.K. from directory"; + Writeback_Nack, desc="Writeback not O.K. from directory"; + + // Triggers + All_acks, desc="Received all required data and message acks"; + All_acks_no_sharers, desc="Received all acks and no other processor has a shared copy"; + } + + // TYPES + + // STRUCTURE DEFINITIONS + + MessageBuffer mandatoryQueue, ordered="false"; + Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])'; + + // CacheEntry + structure(Entry, desc="...", interface="AbstractCacheEntry") { + State CacheState, desc="cache state"; + bool Dirty, desc="Is the data dirty (different than memory)?"; + DataBlock DataBlk, desc="data for the block"; + } + + // TBE fields + structure(TBE, desc="...") { + State TBEState, desc="Transient state"; + DataBlock DataBlk, desc="data for the block, required for concurrent writebacks"; + bool Dirty, desc="Is the data dirty (different than memory)?"; + int NumPendingMsgs, desc="Number of acks/data messages that this processor is waiting for"; + bool Sharers, desc="On a GetS, did we find any other sharers in the system"; + } + + external_type(CacheMemory) { + bool cacheAvail(Address); + Address cacheProbe(Address); + void allocate(Address, Entry); + void deallocate(Address); + Entry lookup(Address); + void changePermission(Address, AccessPermission); + bool isTagPresent(Address); + void profileMiss(CacheMsg); + } + + external_type(TBETable) { + TBE lookup(Address); + void allocate(Address); + void deallocate(Address); + bool isPresent(Address); + } + + TBETable TBEs, template_hack="<L1Cache_TBE>"; + CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])'; + CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])'; + CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["l2cache"])'; + + Entry getCacheEntry(Address addr), return_by_ref="yes" { + if (L2cacheMemory.isTagPresent(addr)) { + return L2cacheMemory[addr]; + } else if (L1DcacheMemory.isTagPresent(addr)) { + return L1DcacheMemory[addr]; + } else { + return L1IcacheMemory[addr]; + } + } + + void changePermission(Address addr, AccessPermission permission) { + if (L2cacheMemory.isTagPresent(addr)) { + return L2cacheMemory.changePermission(addr, permission); + } else if (L1DcacheMemory.isTagPresent(addr)) { + return L1DcacheMemory.changePermission(addr, permission); + } else { + return L1IcacheMemory.changePermission(addr, permission); + } + } + + bool isCacheTagPresent(Address addr) { + return (L2cacheMemory.isTagPresent(addr) || L1DcacheMemory.isTagPresent(addr) || L1IcacheMemory.isTagPresent(addr)); + } + + State getState(Address addr) { + assert((L1DcacheMemory.isTagPresent(addr) && L1IcacheMemory.isTagPresent(addr)) == false); + assert((L1IcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false); + assert((L1DcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false); + + if(TBEs.isPresent(addr)) { + return TBEs[addr].TBEState; + } else if (isCacheTagPresent(addr)) { + return getCacheEntry(addr).CacheState; + } + return State:I; + } + + void setState(Address addr, State state) { + assert((L1DcacheMemory.isTagPresent(addr) && L1IcacheMemory.isTagPresent(addr)) == false); + assert((L1IcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false); + assert((L1DcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false); + + if (TBEs.isPresent(addr)) { + TBEs[addr].TBEState := state; + } + + if (isCacheTagPresent(addr)) { + getCacheEntry(addr).CacheState := state; + + // Set permission + if ((state == State:MM) || + (state == State:MM_W)) { + changePermission(addr, AccessPermission:Read_Write); + } else if (state == State:S || + state == State:O || + state == State:M || + state == State:M_W || + state == State:SM || + state == State:ISM || + state == State:OM || + state == State:SS) { + changePermission(addr, AccessPermission:Read_Only); + } else { + changePermission(addr, AccessPermission:Invalid); + } + } + } + + Event mandatory_request_type_to_event(CacheRequestType type) { + if (type == CacheRequestType:LD) { + return Event:Load; + } else if (type == CacheRequestType:IFETCH) { + return Event:Ifetch; + } else if ((type == CacheRequestType:ST) || (type == CacheRequestType:ATOMIC)) { + return Event:Store; + } else { + error("Invalid CacheRequestType"); + } + } + + MessageBuffer triggerQueue, ordered="true"; + + // ** OUT_PORTS ** + + out_port(requestNetwork_out, RequestMsg, requestFromCache); + out_port(responseNetwork_out, ResponseMsg, responseFromCache); + out_port(unblockNetwork_out, ResponseMsg, unblockFromCache); + out_port(triggerQueue_out, TriggerMsg, triggerQueue); + + // ** IN_PORTS ** + + // Trigger Queue + in_port(triggerQueue_in, TriggerMsg, triggerQueue) { + if (triggerQueue_in.isReady()) { + peek(triggerQueue_in, TriggerMsg) { + if (in_msg.Type == TriggerType:ALL_ACKS) { + trigger(Event:All_acks, in_msg.Address); + } else if (in_msg.Type == TriggerType:ALL_ACKS_NO_SHARERS) { + trigger(Event:All_acks_no_sharers, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + + // Nothing from the request network + + // Forward Network + in_port(forwardToCache_in, RequestMsg, forwardToCache) { + if (forwardToCache_in.isReady()) { + peek(forwardToCache_in, RequestMsg) { + if (in_msg.Type == CoherenceRequestType:GETX) { + trigger(Event:Other_GETX, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:GETS) { + trigger(Event:Other_GETS, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:WB_ACK) { + trigger(Event:Writeback_Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:WB_NACK) { + trigger(Event:Writeback_Nack, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + + // Response Network + in_port(responseToCache_in, ResponseMsg, responseToCache) { + if (responseToCache_in.isReady()) { + peek(responseToCache_in, ResponseMsg) { + if (in_msg.Type == CoherenceResponseType:ACK) { + trigger(Event:Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK_SHARED) { + trigger(Event:Shared_Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA) { + trigger(Event:Data, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) { + trigger(Event:Shared_Data, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { + trigger(Event:Exclusive_Data, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + + // Nothing from the unblock network + + // Mandatory Queue + in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...") { + if (mandatoryQueue_in.isReady()) { + peek(mandatoryQueue_in, CacheMsg) { + + // Check for data access to blocks in I-cache and ifetchs to blocks in D-cache + + if (in_msg.Type == CacheRequestType:IFETCH) { + // ** INSTRUCTION ACCESS *** + + // Check to see if it is in the OTHER L1 + if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) { + // The block is in the wrong L1, try to write it to the L2 + if (L2cacheMemory.cacheAvail(in_msg.LineAddress)) { + trigger(Event:L1_to_L2, in_msg.LineAddress); + } else { + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.LineAddress)); + } + } + + if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) { + // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); + } else { + if (L1IcacheMemory.cacheAvail(in_msg.LineAddress)) { + // L1 does't have the line, but we have space for it in the L1 + if (L2cacheMemory.isTagPresent(in_msg.LineAddress)) { + // L2 has it (maybe not with the right permissions) + trigger(Event:L2_to_L1I, in_msg.LineAddress); + } else { + // We have room, the L2 doesn't have it, so the L1 fetches the line + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); + } + } else { + // No room in the L1, so we need to make room + if (L2cacheMemory.cacheAvail(L1IcacheMemory.cacheProbe(in_msg.LineAddress))) { + // The L2 has room, so we move the line from the L1 to the L2 + trigger(Event:L1_to_L2, L1IcacheMemory.cacheProbe(in_msg.LineAddress)); + } else { + // The L2 does not have room, so we replace a line from the L2 + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1IcacheMemory.cacheProbe(in_msg.LineAddress))); + } + } + } + } else { + // *** DATA ACCESS *** + + // Check to see if it is in the OTHER L1 + if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) { + // The block is in the wrong L1, try to write it to the L2 + if (L2cacheMemory.cacheAvail(in_msg.LineAddress)) { + trigger(Event:L1_to_L2, in_msg.LineAddress); + } else { + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.LineAddress)); + } + } + + if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) { + // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); + } else { + if (L1DcacheMemory.cacheAvail(in_msg.LineAddress)) { + // L1 does't have the line, but we have space for it in the L1 + if (L2cacheMemory.isTagPresent(in_msg.LineAddress)) { + // L2 has it (maybe not with the right permissions) + trigger(Event:L2_to_L1D, in_msg.LineAddress); + } else { + // We have room, the L2 doesn't have it, so the L1 fetches the line + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); + } + } else { + // No room in the L1, so we need to make room + if (L2cacheMemory.cacheAvail(L1DcacheMemory.cacheProbe(in_msg.LineAddress))) { + // The L2 has room, so we move the line from the L1 to the L2 + trigger(Event:L1_to_L2, L1DcacheMemory.cacheProbe(in_msg.LineAddress)); + } else { + // The L2 does not have room, so we replace a line from the L2 + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1DcacheMemory.cacheProbe(in_msg.LineAddress))); + } + } + } + } + } + } + } + + // ACTIONS + + action(a_issueGETS, "a", desc="Issue GETS") { + enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETS; + out_msg.Requestor := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Request_Control; + TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches(); // One from each other cache (n-1) plus the memory (+1) + } + } + + action(b_issueGETX, "b", desc="Issue GETX") { + enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETX; + out_msg.Requestor := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Request_Control; + TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches(); // One from each other cache (n-1) plus the memory (+1) + } + } + + action(c_sendExclusiveData, "c", desc="Send exclusive data from cache to requestor") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; + out_msg.Sender := machineID; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := getCacheEntry(address).DataBlk; + out_msg.Dirty := getCacheEntry(address).Dirty; + out_msg.Acks := 2; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(d_issuePUT, "d", desc="Issue PUT") { + enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:PUT; + out_msg.Requestor := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + + action(e_sendData, "e", desc="Send data from cache to requestor") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA; + out_msg.Sender := machineID; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := getCacheEntry(address).DataBlk; + out_msg.Dirty := getCacheEntry(address).Dirty; + out_msg.Acks := 2; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(ee_sendDataShared, "\e", desc="Send data from cache to requestor, keep a shared copy") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA_SHARED; + out_msg.Sender := machineID; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := getCacheEntry(address).DataBlk; + out_msg.Dirty := getCacheEntry(address).Dirty; + out_msg.Acks := 2; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(f_sendAck, "f", desc="Send ack from cache to requestor") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:ACK; + out_msg.Sender := machineID; + out_msg.Destination.add(in_msg.Requestor); + out_msg.Acks := 1; + out_msg.MessageSize := MessageSizeType:Response_Control; + } + } + } + + action(ff_sendAckShared, "\f", desc="Send shared ack from cache to requestor") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:ACK_SHARED; + out_msg.Sender := machineID; + out_msg.Destination.add(in_msg.Requestor); + out_msg.Acks := 1; + out_msg.MessageSize := MessageSizeType:Response_Control; + } + } + } + + action(g_sendUnblock, "g", desc="Send unblock to memory") { + enqueue(unblockNetwork_out, ResponseMsg, latency=cache_response_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:UNBLOCK; + out_msg.Sender := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Unblock_Control; + } + } + + action(h_load_hit, "h", desc="Notify sequencer the load completed.") { + DEBUG_EXPR(getCacheEntry(address).DataBlk); + sequencer.readCallback(address, getCacheEntry(address).DataBlk); + } + + action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") { + DEBUG_EXPR(getCacheEntry(address).DataBlk); + sequencer.writeCallback(address, getCacheEntry(address).DataBlk); + getCacheEntry(address).Dirty := true; + } + + action(i_allocateTBE, "i", desc="Allocate TBE") { + check_allocate(TBEs); + TBEs.allocate(address); + TBEs[address].DataBlk := getCacheEntry(address).DataBlk; // Data only used for writebacks + TBEs[address].Dirty := getCacheEntry(address).Dirty; + TBEs[address].Sharers := false; + } + + action(j_popTriggerQueue, "j", desc="Pop trigger queue.") { + triggerQueue_in.dequeue(); + } + + action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") { + mandatoryQueue_in.dequeue(); + } + + action(l_popForwardQueue, "l", desc="Pop forwareded request queue.") { + forwardToCache_in.dequeue(); + } + + action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") { + peek(responseToCache_in, ResponseMsg) { + assert(in_msg.Acks > 0); + DEBUG_EXPR(TBEs[address].NumPendingMsgs); + TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - in_msg.Acks; + DEBUG_EXPR(TBEs[address].NumPendingMsgs); + } + } + + action(n_popResponseQueue, "n", desc="Pop response queue") { + responseToCache_in.dequeue(); + } + + action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") { + if (TBEs[address].NumPendingMsgs == 0) { + enqueue(triggerQueue_out, TriggerMsg) { + out_msg.Address := address; + if (TBEs[address].Sharers) { + out_msg.Type := TriggerType:ALL_ACKS; + } else { + out_msg.Type := TriggerType:ALL_ACKS_NO_SHARERS; + } + } + } + } + + action(p_decrementNumberOfMessagesByOne, "p", desc="Decrement the number of messages for which we're waiting by one") { + TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - 1; + } + + action(pp_incrementNumberOfMessagesByOne, "\p", desc="Increment the number of messages for which we're waiting by one") { + TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs + 1; + } + + action(q_sendDataFromTBEToCache, "q", desc="Send data from TBE to cache") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA; + out_msg.Sender := machineID; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.Dirty := TBEs[address].Dirty; + out_msg.Acks := 2; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(qq_sendDataFromTBEToMemory, "\q", desc="Send data from TBE to memory") { + enqueue(unblockNetwork_out, ResponseMsg, latency=cache_response_latency) { + out_msg.Address := address; + out_msg.Sender := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Dirty := TBEs[address].Dirty; + if (TBEs[address].Dirty) { + out_msg.Type := CoherenceResponseType:WB_DIRTY; + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + } else { + out_msg.Type := CoherenceResponseType:WB_CLEAN; + // NOTE: in a real system this would not send data. We send + // data here only so we can check it at the memory + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(r_setSharerBit, "r", desc="We saw other sharers") { + TBEs[address].Sharers := true; + } + + action(s_deallocateTBE, "s", desc="Deallocate TBE") { + TBEs.deallocate(address); + } + + action(t_sendExclusiveDataFromTBEToMemory, "t", desc="Send exclusive data from TBE to memory") { + enqueue(unblockNetwork_out, ResponseMsg, latency=cache_response_latency) { + out_msg.Address := address; + out_msg.Sender := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.Dirty := TBEs[address].Dirty; + if (TBEs[address].Dirty) { + out_msg.Type := CoherenceResponseType:WB_EXCLUSIVE_DIRTY; + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + } else { + out_msg.Type := CoherenceResponseType:WB_EXCLUSIVE_CLEAN; + // NOTE: in a real system this would not send data. We send + // data here only so we can check it at the memory + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(u_writeDataToCache, "u", desc="Write data to cache") { + peek(responseToCache_in, ResponseMsg) { + getCacheEntry(address).DataBlk := in_msg.DataBlk; + getCacheEntry(address).Dirty := in_msg.Dirty; + } + } + + action(v_writeDataToCacheVerify, "v", desc="Write data to cache, assert it was same as before") { + peek(responseToCache_in, ResponseMsg) { + assert(getCacheEntry(address).DataBlk == in_msg.DataBlk); + getCacheEntry(address).DataBlk := in_msg.DataBlk; + getCacheEntry(address).Dirty := in_msg.Dirty; + } + } + + action(gg_deallocateL1CacheBlock, "\g", desc="Deallocate cache block. Sets the cache to invalid, allowing a replacement in parallel with a fetch.") { + if (L1DcacheMemory.isTagPresent(address)) { + L1DcacheMemory.deallocate(address); + } else { + L1IcacheMemory.deallocate(address); + } + } + + action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") { + if (L1DcacheMemory.isTagPresent(address) == false) { + L1DcacheMemory.allocate(address, new Entry); + } + } + + action(jj_allocateL1ICacheBlock, "\j", desc="Set L1 I-cache tag equal to tag of block B.") { + if (L1IcacheMemory.isTagPresent(address) == false) { + L1IcacheMemory.allocate(address, new Entry); + } + } + + action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") { + L2cacheMemory.allocate(address, new Entry); + } + + action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") { + L2cacheMemory.deallocate(address); + } + + action(ss_copyFromL1toL2, "\s", desc="Copy data block from L1 (I or D) to L2") { + if (L1DcacheMemory.isTagPresent(address)) { + L2cacheMemory[address] := L1DcacheMemory[address]; + } else { + L2cacheMemory[address] := L1IcacheMemory[address]; + } + } + + action(tt_copyFromL2toL1, "\t", desc="Copy data block from L2 to L1 (I or D)") { + if (L1DcacheMemory.isTagPresent(address)) { + L1DcacheMemory[address] := L2cacheMemory[address]; + } else { + L1IcacheMemory[address] := L2cacheMemory[address]; + } + } + + action(uu_profileMiss, "\u", desc="Profile the demand miss") { + peek(mandatoryQueue_in, CacheMsg) { + if (L1IcacheMemory.isTagPresent(address)) { + L1IcacheMemory.profileMiss(in_msg); + } else if (L1DcacheMemory.isTagPresent(address)) { + L1DcacheMemory.profileMiss(in_msg); + } else { + L2cacheMemory.profileMiss(in_msg); + } + } + } + + action(zz_recycleMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") { + mandatoryQueue_in.recycle(); + } + + //***************************************************** + // TRANSITIONS + //***************************************************** + + // Transitions for Load/Store/L2_Replacement from transient states + transition({IM, SM, ISM, OM, IS, SS, OI, MI, II}, {Store, L2_Replacement}) { + zz_recycleMandatoryQueue; + } + + transition({M_W, MM_W}, {L2_Replacement}) { + zz_recycleMandatoryQueue; + } + + transition({IM, IS, OI, MI, II}, {Load, Ifetch}) { + zz_recycleMandatoryQueue; + } + + transition({IM, SM, ISM, OM, IS, SS, MM_W, M_W, OI, MI, II}, L1_to_L2) { + zz_recycleMandatoryQueue; + } + + // Transitions moving data between the L1 and L2 caches + transition({I, S, O, M, MM}, L1_to_L2) { + vv_allocateL2CacheBlock; + ss_copyFromL1toL2; // Not really needed for state I + gg_deallocateL1CacheBlock; + } + + transition({I, S, O, M, MM}, L2_to_L1D) { + ii_allocateL1DCacheBlock; + tt_copyFromL2toL1; // Not really needed for state I + rr_deallocateL2CacheBlock; + } + + transition({I, S, O, M, MM}, L2_to_L1I) { + jj_allocateL1ICacheBlock; + tt_copyFromL2toL1; // Not really needed for state I + rr_deallocateL2CacheBlock; + } + + // Transitions from Idle + transition(I, Load, IS) { + ii_allocateL1DCacheBlock; + i_allocateTBE; + a_issueGETS; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(I, Ifetch, IS) { + jj_allocateL1ICacheBlock; + i_allocateTBE; + a_issueGETS; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(I, Store, IM) { + ii_allocateL1DCacheBlock; + i_allocateTBE; + b_issueGETX; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(I, L2_Replacement) { + rr_deallocateL2CacheBlock; + } + + transition(I, {Other_GETX, Other_GETS}) { + f_sendAck; + l_popForwardQueue; + } + + // Transitions from Shared + transition({S, SM, ISM}, {Load, Ifetch}) { + h_load_hit; + k_popMandatoryQueue; + } + + transition(S, Store, SM) { + i_allocateTBE; + b_issueGETX; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(S, L2_Replacement, I) { + rr_deallocateL2CacheBlock; + } + + transition(S, Other_GETX, I) { + f_sendAck; + l_popForwardQueue; + } + + transition(S, Other_GETS) { + ff_sendAckShared; + l_popForwardQueue; + } + + // Transitions from Owned + transition({O, OM, SS, MM_W, M_W}, {Load, Ifetch}) { + h_load_hit; + k_popMandatoryQueue; + } + + transition(O, Store, OM) { + i_allocateTBE; + b_issueGETX; + p_decrementNumberOfMessagesByOne; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(O, L2_Replacement, OI) { + i_allocateTBE; + d_issuePUT; + rr_deallocateL2CacheBlock; + } + + transition(O, Other_GETX, I) { + e_sendData; + l_popForwardQueue; + } + + transition(O, Other_GETS) { + ee_sendDataShared; + l_popForwardQueue; + } + + // Transitions from Modified + transition(MM, {Load, Ifetch}) { + h_load_hit; + k_popMandatoryQueue; + } + + transition(MM, Store) { + hh_store_hit; + k_popMandatoryQueue; + } + + transition(MM, L2_Replacement, MI) { + i_allocateTBE; + d_issuePUT; + rr_deallocateL2CacheBlock; + } + + transition(MM, Other_GETX, I) { + c_sendExclusiveData; + l_popForwardQueue; + } + + transition(MM, Other_GETS, I) { + c_sendExclusiveData; + l_popForwardQueue; + } + + // Transitions from Dirty Exclusive + transition(M, {Load, Ifetch}) { + h_load_hit; + k_popMandatoryQueue; + } + + transition(M, Store, MM) { + hh_store_hit; + k_popMandatoryQueue; + } + + transition(M, L2_Replacement, MI) { + i_allocateTBE; + d_issuePUT; + rr_deallocateL2CacheBlock; + } + + transition(M, Other_GETX, I) { + c_sendExclusiveData; + l_popForwardQueue; + } + + transition(M, Other_GETS, O) { + ee_sendDataShared; + l_popForwardQueue; + } + + // Transitions from IM + + transition(IM, {Other_GETX, Other_GETS}) { + f_sendAck; + l_popForwardQueue; + } + + transition(IM, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(IM, Data, ISM) { + u_writeDataToCache; + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(IM, Exclusive_Data, MM_W) { + u_writeDataToCache; + m_decrementNumberOfMessages; + o_checkForCompletion; + hh_store_hit; + n_popResponseQueue; + } + + // Transitions from SM + transition(SM, Other_GETS) { + ff_sendAckShared; + l_popForwardQueue; + } + + transition(SM, Other_GETX, IM) { + f_sendAck; + l_popForwardQueue; + } + + transition(SM, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(SM, Data, ISM) { + v_writeDataToCacheVerify; + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + // Transitions from ISM + transition(ISM, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(ISM, All_acks_no_sharers, MM) { + hh_store_hit; + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from OM + + transition(OM, Other_GETX, IM) { + e_sendData; + pp_incrementNumberOfMessagesByOne; + l_popForwardQueue; + } + + transition(OM, Other_GETS) { + ee_sendDataShared; + l_popForwardQueue; + } + + transition(OM, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(OM, {All_acks, All_acks_no_sharers}, MM) { + hh_store_hit; + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from IS + + transition(IS, {Other_GETX, Other_GETS}) { + f_sendAck; + l_popForwardQueue; + } + + transition(IS, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(IS, Shared_Ack) { + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(IS, Data, SS) { + u_writeDataToCache; + m_decrementNumberOfMessages; + o_checkForCompletion; + h_load_hit; + n_popResponseQueue; + } + + transition(IS, Exclusive_Data, M_W) { + u_writeDataToCache; + m_decrementNumberOfMessages; + o_checkForCompletion; + h_load_hit; + n_popResponseQueue; + } + + transition(IS, Shared_Data, SS) { + u_writeDataToCache; + r_setSharerBit; + m_decrementNumberOfMessages; + o_checkForCompletion; + h_load_hit; + n_popResponseQueue; + } + + // Transitions from SS + + transition(SS, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(SS, Shared_Ack) { + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(SS, All_acks, S) { + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + transition(SS, All_acks_no_sharers, S) { + // Note: The directory might still be the owner, so that is why we go to S + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from MM_W + + transition(MM_W, Store) { + hh_store_hit; + k_popMandatoryQueue; + } + + transition(MM_W, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(MM_W, All_acks_no_sharers, MM) { + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from M_W + + transition(M_W, Store, MM_W) { + hh_store_hit; + k_popMandatoryQueue; + } + + transition(M_W, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(M_W, All_acks_no_sharers, M) { + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from OI/MI + + transition({OI, MI}, Other_GETX, II) { + q_sendDataFromTBEToCache; + l_popForwardQueue; + } + + transition({OI, MI}, Other_GETS, OI) { + q_sendDataFromTBEToCache; + l_popForwardQueue; + } + + transition(MI, Writeback_Ack, I) { + t_sendExclusiveDataFromTBEToMemory; + s_deallocateTBE; + l_popForwardQueue; + } + + transition(OI, Writeback_Ack, I) { + qq_sendDataFromTBEToMemory; + s_deallocateTBE; + l_popForwardQueue; + } + + // Transitions from II + transition(II, {Other_GETS, Other_GETX}, II) { + f_sendAck; + l_popForwardQueue; + } + + transition(II, Writeback_Ack, I) { + g_sendUnblock; + s_deallocateTBE; + l_popForwardQueue; + } + + transition(II, Writeback_Nack, I) { + s_deallocateTBE; + l_popForwardQueue; + } +} + diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm new file mode 100644 index 000000000..b9b001e40 --- /dev/null +++ b/src/mem/protocol/MOESI_hammer-dir.sm @@ -0,0 +1,920 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * AMD's contributions to the MOESI hammer protocol do not constitute an + * endorsement of its similarity to any AMD products. + * + * Authors: Milo Martin + * Brad Beckmann + */ + +machine(Directory, "AMD Hammer-like protocol") +: int memory_controller_latency +{ + + MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false"; + MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false"; + // + // For a finite buffered network, note that the DMA response network only + // works at this relatively higher numbered (lower priority) virtual network + // because the trigger queue decouples cache responses from DMA responses. + // + MessageBuffer dmaResponseFromDir, network="To", virtual_network="4", ordered="true"; + + MessageBuffer unblockToDir, network="From", virtual_network="0", ordered="false"; + MessageBuffer responseToDir, network="From", virtual_network="1", ordered="false"; + MessageBuffer requestToDir, network="From", virtual_network="3", ordered="false"; + MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true"; + + // STATES + enumeration(State, desc="Directory states", default="Directory_State_E") { + // Base states + NO, desc="Not Owner"; + O, desc="Owner"; + E, desc="Exclusive Owner (we can provide the data in exclusive)"; + NO_B, "NO^B", desc="Not Owner, Blocked"; + O_B, "O^B", desc="Owner, Blocked"; + NO_B_W, desc="Not Owner, Blocked, waiting for Dram"; + O_B_W, desc="Owner, Blocked, waiting for Dram"; + NO_W, desc="Not Owner, waiting for Dram"; + O_W, desc="Owner, waiting for Dram"; + NO_DW_B_W, desc="Not Owner, Dma Write waiting for Dram and cache responses"; + NO_DR_B_W, desc="Not Owner, Dma Read waiting for Dram and cache responses"; + NO_DR_B_D, desc="Not Owner, Dma Read waiting for cache responses including dirty data"; + NO_DR_B, desc="Not Owner, Dma Read waiting for cache responses"; + NO_DW_W, desc="Not Owner, Dma Write waiting for Dram"; + O_DR_B_W, desc="Owner, Dma Read waiting for Dram and cache responses"; + O_DR_B, desc="Owner, Dma Read waiting for cache responses"; + WB, desc="Blocked on a writeback"; + WB_O_W, desc="Blocked on memory write, will go to O"; + WB_E_W, desc="Blocked on memory write, will go to E"; + } + + // Events + enumeration(Event, desc="Directory events") { + GETX, desc="A GETX arrives"; + GETS, desc="A GETS arrives"; + PUT, desc="A PUT arrives"; + Unblock, desc="An unblock message arrives"; + Writeback_Clean, desc="The final part of a PutX (no data)"; + Writeback_Dirty, desc="The final part of a PutX (data)"; + Writeback_Exclusive_Clean, desc="The final part of a PutX (no data, exclusive)"; + Writeback_Exclusive_Dirty, desc="The final part of a PutX (data, exclusive)"; + + // DMA requests + DMA_READ, desc="A DMA Read memory request"; + DMA_WRITE, desc="A DMA Write memory request"; + + // Memory Controller + Memory_Data, desc="Fetched data from memory arrives"; + Memory_Ack, desc="Writeback Ack from memory arrives"; + + // Cache responses required to handle DMA + Ack, desc="Received an ack message"; + Shared_Ack, desc="Received an ack message, responder has a shared copy"; + Shared_Data, desc="Received a data message, responder has a shared copy"; + Exclusive_Data, desc="Received a data message, responder had an exclusive copy, they gave it to us"; + + // Triggers + All_acks_and_data, desc="Received all required data and message acks"; + All_acks_and_data_no_sharers, desc="Received all acks and no other processor has a shared copy"; + } + + // TYPES + + // DirectoryEntry + structure(Entry, desc="...") { + State DirectoryState, desc="Directory state"; + DataBlock DataBlk, desc="data for the block"; + } + + external_type(DirectoryMemory) { + Entry lookup(Address); + bool isPresent(Address); + } + + external_type(MemoryControl, inport="yes", outport="yes") { + + } + + // TBE entries for DMA requests + structure(TBE, desc="TBE entries for outstanding DMA requests") { + Address PhysicalAddress, desc="physical address"; + State TBEState, desc="Transient State"; + CoherenceResponseType ResponseType, desc="The type for the subsequent response message"; + DataBlock DmaDataBlk, desc="DMA Data to be written. Partial blocks need to merged with system memory"; + DataBlock DataBlk, desc="The current view of system memory"; + int Len, desc="..."; + MachineID DmaRequestor, desc="DMA requestor"; + int NumPendingMsgs, desc="Number of pending acks/messages"; + bool CacheDirty, desc="Indicates whether a cache has responded with dirty data"; + bool Sharers, desc="Indicates whether a cache has indicated it is currently a sharer"; + } + + external_type(TBETable) { + TBE lookup(Address); + void allocate(Address); + void deallocate(Address); + bool isPresent(Address); + } + + // ** OBJECTS ** + + DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])'; + + MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])'; + + TBETable TBEs, template_hack="<Directory_TBE>"; + + State getState(Address addr) { + if (TBEs.isPresent(addr)) { + return TBEs[addr].TBEState; + } else { + return directory[addr].DirectoryState; + } + } + + void setState(Address addr, State state) { + if (TBEs.isPresent(addr)) { + TBEs[addr].TBEState := state; + } + directory[addr].DirectoryState := state; + } + + MessageBuffer triggerQueue, ordered="true"; + + // ** OUT_PORTS ** + out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests + out_port(forwardNetwork_out, RequestMsg, forwardFromDir); + out_port(responseNetwork_out, ResponseMsg, responseFromDir); + out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir); + out_port(triggerQueue_out, TriggerMsg, triggerQueue); + + // + // Memory buffer for memory controller to DIMM communication + // + out_port(memQueue_out, MemoryMsg, memBuffer); + + // ** IN_PORTS ** + + // Trigger Queue + in_port(triggerQueue_in, TriggerMsg, triggerQueue) { + if (triggerQueue_in.isReady()) { + peek(triggerQueue_in, TriggerMsg) { + if (in_msg.Type == TriggerType:ALL_ACKS) { + trigger(Event:All_acks_and_data, in_msg.Address); + } else if (in_msg.Type == TriggerType:ALL_ACKS_NO_SHARERS) { + trigger(Event:All_acks_and_data_no_sharers, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + + in_port(unblockNetwork_in, ResponseMsg, unblockToDir) { + if (unblockNetwork_in.isReady()) { + peek(unblockNetwork_in, ResponseMsg) { + if (in_msg.Type == CoherenceResponseType:UNBLOCK) { + trigger(Event:Unblock, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:WB_CLEAN) { + trigger(Event:Writeback_Clean, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:WB_DIRTY) { + trigger(Event:Writeback_Dirty, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:WB_EXCLUSIVE_CLEAN) { + trigger(Event:Writeback_Exclusive_Clean, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:WB_EXCLUSIVE_DIRTY) { + trigger(Event:Writeback_Exclusive_Dirty, in_msg.Address); + } else { + error("Invalid message"); + } + } + } + } + + // Response Network + in_port(responseToDir_in, ResponseMsg, responseToDir) { + if (responseToDir_in.isReady()) { + peek(responseToDir_in, ResponseMsg) { + if (in_msg.Type == CoherenceResponseType:ACK) { + trigger(Event:Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK_SHARED) { + trigger(Event:Shared_Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) { + trigger(Event:Shared_Data, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { + trigger(Event:Exclusive_Data, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + + in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) { + if (dmaRequestQueue_in.isReady()) { + peek(dmaRequestQueue_in, DMARequestMsg) { + if (in_msg.Type == DMARequestType:READ) { + trigger(Event:DMA_READ, in_msg.LineAddress); + } else if (in_msg.Type == DMARequestType:WRITE) { + trigger(Event:DMA_WRITE, in_msg.LineAddress); + } else { + error("Invalid message"); + } + } + } + } + + in_port(requestQueue_in, RequestMsg, requestToDir) { + if (requestQueue_in.isReady()) { + peek(requestQueue_in, RequestMsg) { + if (in_msg.Type == CoherenceRequestType:GETS) { + trigger(Event:GETS, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:GETX) { + trigger(Event:GETX, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:PUT) { + trigger(Event:PUT, in_msg.Address); + } else { + error("Invalid message"); + } + } + } + } + + // off-chip memory request/response is done + in_port(memQueue_in, MemoryMsg, memBuffer) { + if (memQueue_in.isReady()) { + peek(memQueue_in, MemoryMsg) { + if (in_msg.Type == MemoryRequestType:MEMORY_READ) { + trigger(Event:Memory_Data, in_msg.Address); + } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) { + trigger(Event:Memory_Ack, in_msg.Address); + } else { + DEBUG_EXPR(in_msg.Type); + error("Invalid message"); + } + } + } + } + + // Actions + + action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") { + peek(requestQueue_in, RequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:WB_ACK; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.add(in_msg.Requestor); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") { + peek(requestQueue_in, RequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:WB_NACK; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.add(in_msg.Requestor); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(v_allocateTBE, "v", desc="Allocate TBE") { + peek(requestQueue_in, RequestMsg) { + TBEs.allocate(address); + TBEs[address].PhysicalAddress := address; + TBEs[address].ResponseType := CoherenceResponseType:NULL; + } + } + + action(vd_allocateDmaRequestInTBE, "vd", desc="Record Data in TBE") { + peek(dmaRequestQueue_in, DMARequestMsg) { + TBEs.allocate(address); + TBEs[address].DmaDataBlk := in_msg.DataBlk; + TBEs[address].PhysicalAddress := in_msg.PhysicalAddress; + TBEs[address].Len := in_msg.Len; + TBEs[address].DmaRequestor := in_msg.Requestor; + TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE; + // + // One ack for each last-level cache + // + TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches(); + // + // Assume initially that the caches store a clean copy and that memory + // will provide the data + // + TBEs[address].CacheDirty := false; + } + } + + action(w_deallocateTBE, "w", desc="Deallocate TBE") { + TBEs.deallocate(address); + } + + action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") { + peek(responseToDir_in, ResponseMsg) { + assert(in_msg.Acks > 0); + DEBUG_EXPR(TBEs[address].NumPendingMsgs); + // + // Note that cache data responses will have an ack count of 2. However, + // directory DMA requests must wait for acks from all LLC caches, so + // only decrement by 1. + // + TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - 1; + DEBUG_EXPR(TBEs[address].NumPendingMsgs); + } + } + + action(n_popResponseQueue, "n", desc="Pop response queue") { + responseToDir_in.dequeue(); + } + + action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") { + if (TBEs[address].NumPendingMsgs == 0) { + enqueue(triggerQueue_out, TriggerMsg) { + out_msg.Address := address; + if (TBEs[address].Sharers) { + out_msg.Type := TriggerType:ALL_ACKS; + } else { + out_msg.Type := TriggerType:ALL_ACKS_NO_SHARERS; + } + } + } + } + + action(d_sendData, "d", desc="Send data to requestor") { + peek(memQueue_in, MemoryMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := TBEs[address].ResponseType; + out_msg.Sender := machineID; + out_msg.Destination.add(in_msg.OriginalRequestorMachId); + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Dirty := false; // By definition, the block is now clean + out_msg.Acks := 1; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(dr_sendDmaData, "dr", desc="Send Data to DMA controller from memory") { + peek(memQueue_in, MemoryMsg) { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:DATA; + // + // we send the entire data block and rely on the dma controller to + // split it up if need be + // + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(dt_sendDmaDataFromTbe, "dt", desc="Send Data to DMA controller from tbe") { + peek(triggerQueue_in, TriggerMsg) { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:DATA; + // + // we send the entire data block and rely on the dma controller to + // split it up if need be + // + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(da_sendDmaAck, "da", desc="Send Ack to DMA controller") { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:ACK; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + + action(rx_recordExclusiveInTBE, "rx", desc="Record Exclusive in TBE") { + peek(requestQueue_in, RequestMsg) { + TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE; + } + } + + action(r_recordDataInTBE, "rt", desc="Record Data in TBE") { + peek(requestQueue_in, RequestMsg) { + TBEs[address].ResponseType := CoherenceResponseType:DATA; + } + } + + action(r_setSharerBit, "r", desc="We saw other sharers") { + TBEs[address].Sharers := true; + } + + action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { + peek(requestQueue_in, RequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := in_msg.Requestor; + out_msg.MessageSize := in_msg.MessageSize; + out_msg.DataBlk := directory[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + } + + action(qd_queueMemoryRequestFromDmaRead, "qd", desc="Queue off-chip fetch request") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := in_msg.Requestor; + out_msg.MessageSize := in_msg.MessageSize; + out_msg.DataBlk := directory[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + } + + action(f_forwardRequest, "f", desc="Forward requests") { + if (getNumberOfLastLevelCaches() > 1) { + peek(requestQueue_in, RequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := in_msg.Type; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.broadcast(MachineType:L1Cache); // Send to all L1 caches + out_msg.Destination.remove(in_msg.Requestor); // Don't include the original requestor + out_msg.MessageSize := MessageSizeType:Forwarded_Control; + } + } + } + } + + action(f_forwardWriteFromDma, "fw", desc="Forward requests") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETX; + // + // Send to all L1 caches, since the requestor is the memory controller + // itself + // + out_msg.Requestor := machineID; + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.MessageSize := MessageSizeType:Forwarded_Control; + } + } + } + + action(f_forwardReadFromDma, "fr", desc="Forward requests") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETS; + // + // Send to all L1 caches, since the requestor is the memory controller + // itself + // + out_msg.Requestor := machineID; + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.MessageSize := MessageSizeType:Forwarded_Control; + } + } + } + + action(i_popIncomingRequestQueue, "i", desc="Pop incoming request queue") { + requestQueue_in.dequeue(); + } + + action(j_popIncomingUnblockQueue, "j", desc="Pop incoming unblock queue") { + unblockNetwork_in.dequeue(); + } + + action(l_popMemQueue, "q", desc="Pop off-chip request queue") { + memQueue_in.dequeue(); + } + + action(g_popTriggerQueue, "g", desc="Pop trigger queue") { + triggerQueue_in.dequeue(); + } + + action(p_popDmaRequestQueue, "pd", desc="pop dma request queue") { + dmaRequestQueue_in.dequeue(); + } + + action(y_recycleDmaRequestQueue, "y", desc="recycle dma request queue") { + dmaRequestQueue_in.recycle(); + } + + action(r_recordMemoryData, "rd", desc="record data from memory to TBE") { + peek(memQueue_in, MemoryMsg) { + if (TBEs[address].CacheDirty == false) { + TBEs[address].DataBlk := in_msg.DataBlk; + } + } + } + + action(r_recordCacheData, "rc", desc="record data from cache response to TBE") { + peek(responseToDir_in, ResponseMsg) { + TBEs[address].CacheDirty := true; + TBEs[address].DataBlk := in_msg.DataBlk; + } + } + + action(l_writeDataToMemory, "l", desc="Write PUTX/PUTO data to memory") { + peek(unblockNetwork_in, ResponseMsg) { + assert(in_msg.Dirty); + assert(in_msg.MessageSize == MessageSizeType:Writeback_Data); + directory[address].DataBlk := in_msg.DataBlk; + DEBUG_EXPR(in_msg.Address); + DEBUG_EXPR(in_msg.DataBlk); + } + } + + action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") { + directory[address].DataBlk := TBEs[address].DataBlk; + directory[address].DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + } + + action(a_assertCacheData, "ac", desc="Assert that a cache provided the data") { + assert(TBEs[address].CacheDirty); + } + + action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") { + peek(unblockNetwork_in, ResponseMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + DEBUG_EXPR(out_msg); + } + } + } + + action(ld_queueMemoryDmaWrite, "ld", desc="Write DMA data to memory") { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + // first, initialize the data blk to the current version of system memory + out_msg.DataBlk := TBEs[address].DataBlk; + // then add the dma write data + out_msg.DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + DEBUG_EXPR(out_msg); + } + } + + action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") { + peek(unblockNetwork_in, ResponseMsg) { + assert(in_msg.Dirty == false); + assert(in_msg.MessageSize == MessageSizeType:Writeback_Control); + + // NOTE: The following check would not be valid in a real + // implementation. We include the data in the "dataless" + // message so we can assert the clean data matches the datablock + // in memory + assert(directory[address].DataBlk == in_msg.DataBlk); + } + } + + action(zz_recycleRequest, "\z", desc="Recycle the request queue") { + requestQueue_in.recycle(); + } + + // TRANSITIONS + + // Transitions out of E state + transition(E, GETX, NO_B_W) { + v_allocateTBE; + rx_recordExclusiveInTBE; + qf_queueMemoryFetchRequest; + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(E, GETS, NO_B_W) { + v_allocateTBE; + rx_recordExclusiveInTBE; + qf_queueMemoryFetchRequest; + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(E, DMA_READ, NO_DR_B_W) { + vd_allocateDmaRequestInTBE; + qd_queueMemoryRequestFromDmaRead; + f_forwardReadFromDma; + p_popDmaRequestQueue; + } + + // Transitions out of O state + transition(O, GETX, NO_B_W) { + v_allocateTBE; + r_recordDataInTBE; + qf_queueMemoryFetchRequest; + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(O, GETS, O_B_W) { + v_allocateTBE; + r_recordDataInTBE; + qf_queueMemoryFetchRequest; + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(O, DMA_READ, O_DR_B_W) { + vd_allocateDmaRequestInTBE; + qd_queueMemoryRequestFromDmaRead; + f_forwardReadFromDma; + p_popDmaRequestQueue; + } + + transition({E, O, NO}, DMA_WRITE, NO_DW_B_W) { + vd_allocateDmaRequestInTBE; + f_forwardWriteFromDma; + p_popDmaRequestQueue; + } + + // Transitions out of NO state + transition(NO, GETX, NO_B) { + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(NO, GETS, NO_B) { + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(NO, PUT, WB) { + a_sendWriteBackAck; + i_popIncomingRequestQueue; + } + + transition(NO, DMA_READ, NO_DR_B_D) { + vd_allocateDmaRequestInTBE; + f_forwardReadFromDma; + p_popDmaRequestQueue; + } + + // Nack PUT requests when races cause us to believe we own the data + transition({O, E}, PUT) { + b_sendWriteBackNack; + i_popIncomingRequestQueue; + } + + // Blocked transient states + transition({NO_B, O_B, NO_DR_B_W, NO_DW_B_W, NO_B_W, NO_DR_B_D, + NO_DR_B, O_DR_B, O_B_W, O_DR_B_W, NO_DW_W, + NO_W, O_W, WB, WB_E_W, WB_O_W}, + {GETS, GETX, PUT}) { + zz_recycleRequest; + } + + transition({NO_B, O_B, NO_DR_B_W, NO_DW_B_W, NO_B_W, NO_DR_B_D, + NO_DR_B, O_DR_B, O_B_W, O_DR_B_W, NO_DW_W, + NO_W, O_W, WB, WB_E_W, WB_O_W}, + {DMA_READ, DMA_WRITE}) { + y_recycleDmaRequestQueue; + } + + transition(NO_B, Unblock, NO) { + j_popIncomingUnblockQueue; + } + + transition(O_B, Unblock, O) { + j_popIncomingUnblockQueue; + } + + transition(NO_B_W, Memory_Data, NO_B) { + d_sendData; + w_deallocateTBE; + l_popMemQueue; + } + + transition(NO_DR_B_W, Memory_Data, NO_DR_B) { + r_recordMemoryData; + o_checkForCompletion; + l_popMemQueue; + } + + transition(O_DR_B_W, Memory_Data, O_DR_B) { + r_recordMemoryData; + dr_sendDmaData; + o_checkForCompletion; + l_popMemQueue; + } + + transition({NO_DR_B, O_DR_B, NO_DR_B_D, NO_DW_B_W}, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(NO_DR_B_W, Ack) { + m_decrementNumberOfMessages; + n_popResponseQueue; + } + + transition(NO_DR_B_W, Shared_Ack) { + m_decrementNumberOfMessages; + r_setSharerBit; + n_popResponseQueue; + } + + transition({NO_DR_B, NO_DR_B_D}, Shared_Ack) { + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(NO_DR_B_W, Shared_Data) { + r_recordCacheData; + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition({NO_DR_B, NO_DR_B_D}, Shared_Data) { + r_recordCacheData; + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(NO_DR_B_W, Exclusive_Data) { + r_recordCacheData; + m_decrementNumberOfMessages; + n_popResponseQueue; + } + + transition({NO_DR_B, NO_DR_B_D, NO_DW_B_W}, Exclusive_Data) { + r_recordCacheData; + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(NO_DR_B, All_acks_and_data, O) { + // + // Note that the DMA consistency model allows us to send the DMA device + // a response as soon as we receive valid data and prior to receiving + // all acks. However, to simplify the protocol we wait for all acks. + // + dt_sendDmaDataFromTbe; + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(NO_DR_B_D, All_acks_and_data, O) { + // + // Note that the DMA consistency model allows us to send the DMA device + // a response as soon as we receive valid data and prior to receiving + // all acks. However, to simplify the protocol we wait for all acks. + // + dt_sendDmaDataFromTbe; + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(O_DR_B, All_acks_and_data_no_sharers, O) { + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(NO_DR_B, All_acks_and_data_no_sharers, E) { + // + // Note that the DMA consistency model allows us to send the DMA device + // a response as soon as we receive valid data and prior to receiving + // all acks. However, to simplify the protocol we wait for all acks. + // + dt_sendDmaDataFromTbe; + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(NO_DR_B_D, All_acks_and_data_no_sharers, E) { + a_assertCacheData; + // + // Note that the DMA consistency model allows us to send the DMA device + // a response as soon as we receive valid data and prior to receiving + // all acks. However, to simplify the protocol we wait for all acks. + // + dt_sendDmaDataFromTbe; + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(NO_DW_B_W, All_acks_and_data_no_sharers, NO_DW_W) { + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWrite; + g_popTriggerQueue; + } + + transition(NO_DW_W, Memory_Ack, E) { + da_sendDmaAck; + w_deallocateTBE; + l_popMemQueue; + } + + transition(O_B_W, Memory_Data, O_B) { + d_sendData; + w_deallocateTBE; + l_popMemQueue; + } + + transition(NO_B_W, Unblock, NO_W) { + j_popIncomingUnblockQueue; + } + + transition(O_B_W, Unblock, O_W) { + j_popIncomingUnblockQueue; + } + + transition(NO_W, Memory_Data, NO) { + w_deallocateTBE; + l_popMemQueue; + } + + transition(O_W, Memory_Data, O) { + w_deallocateTBE; + l_popMemQueue; + } + + // WB State Transistions + transition(WB, Writeback_Dirty, WB_E_W) { + l_writeDataToMemory; + l_queueMemoryWBRequest; + j_popIncomingUnblockQueue; + } + + transition(WB, Writeback_Exclusive_Dirty, WB_O_W) { + l_writeDataToMemory; + l_queueMemoryWBRequest; + j_popIncomingUnblockQueue; + } + + transition(WB_E_W, Memory_Ack, E) { + l_popMemQueue; + } + + transition(WB_O_W, Memory_Ack, O) { + l_popMemQueue; + } + + transition(WB, Writeback_Clean, O) { + ll_checkIncomingWriteback; + j_popIncomingUnblockQueue; + } + + transition(WB, Writeback_Exclusive_Clean, E) { + ll_checkIncomingWriteback; + j_popIncomingUnblockQueue; + } + + transition(WB, Unblock, NO) { + j_popIncomingUnblockQueue; + } +} diff --git a/src/mem/protocol/MOESI_hammer-dma.sm b/src/mem/protocol/MOESI_hammer-dma.sm new file mode 100644 index 000000000..b217923a4 --- /dev/null +++ b/src/mem/protocol/MOESI_hammer-dma.sm @@ -0,0 +1,165 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +machine(DMA, "DMA Controller") +: int request_latency +{ + + MessageBuffer responseFromDir, network="From", virtual_network="4", ordered="true", no_vector="true"; + MessageBuffer reqToDirectory, network="To", virtual_network="5", ordered="false", no_vector="true"; + + enumeration(State, desc="DMA states", default="DMA_State_READY") { + READY, desc="Ready to accept a new request"; + BUSY_RD, desc="Busy: currently processing a request"; + BUSY_WR, desc="Busy: currently processing a request"; + } + + enumeration(Event, desc="DMA events") { + ReadRequest, desc="A new read request"; + WriteRequest, desc="A new write request"; + Data, desc="Data from a DMA memory read"; + Ack, desc="DMA write to memory completed"; + } + + external_type(DMASequencer) { + void ackCallback(); + void dataCallback(DataBlock); + } + + MessageBuffer mandatoryQueue, ordered="false", no_vector="true"; + DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])', no_vector="true"; + State cur_state, no_vector="true"; + + State getState(Address addr) { + return cur_state; + } + void setState(Address addr, State state) { + cur_state := state; + } + + out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="..."); + + in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") { + if (dmaRequestQueue_in.isReady()) { + peek(dmaRequestQueue_in, SequencerMsg) { + if (in_msg.Type == SequencerRequestType:LD ) { + trigger(Event:ReadRequest, in_msg.LineAddress); + } else if (in_msg.Type == SequencerRequestType:ST) { + trigger(Event:WriteRequest, in_msg.LineAddress); + } else { + error("Invalid request type"); + } + } + } + } + + in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") { + if (dmaResponseQueue_in.isReady()) { + peek( dmaResponseQueue_in, DMAResponseMsg) { + if (in_msg.Type == DMAResponseType:ACK) { + trigger(Event:Ack, in_msg.LineAddress); + } else if (in_msg.Type == DMAResponseType:DATA) { + trigger(Event:Data, in_msg.LineAddress); + } else { + error("Invalid response type"); + } + } + } + } + + action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") { + peek(dmaRequestQueue_in, SequencerMsg) { + enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) { + out_msg.PhysicalAddress := in_msg.PhysicalAddress; + out_msg.LineAddress := in_msg.LineAddress; + out_msg.Type := DMARequestType:READ; + out_msg.Requestor := machineID; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") { + peek(dmaRequestQueue_in, SequencerMsg) { + enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) { + out_msg.PhysicalAddress := in_msg.PhysicalAddress; + out_msg.LineAddress := in_msg.LineAddress; + out_msg.Type := DMARequestType:WRITE; + out_msg.Requestor := machineID; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(a_ackCallback, "a", desc="Notify dma controller that write request completed") { + peek (dmaResponseQueue_in, DMAResponseMsg) { + dma_sequencer.ackCallback(); + } + } + + action(d_dataCallback, "d", desc="Write data to dma sequencer") { + peek (dmaResponseQueue_in, DMAResponseMsg) { + dma_sequencer.dataCallback(in_msg.DataBlk); + } + } + + action(p_popRequestQueue, "p", desc="Pop request queue") { + dmaRequestQueue_in.dequeue(); + } + + action(p_popResponseQueue, "\p", desc="Pop request queue") { + dmaResponseQueue_in.dequeue(); + } + + transition(READY, ReadRequest, BUSY_RD) { + s_sendReadRequest; + p_popRequestQueue; + } + + transition(READY, WriteRequest, BUSY_WR) { + s_sendWriteRequest; + p_popRequestQueue; + } + + transition(BUSY_RD, Data, READY) { + d_dataCallback; + p_popResponseQueue; + } + + transition(BUSY_WR, Ack, READY) { + a_ackCallback; + p_popResponseQueue; + } +} diff --git a/src/mem/protocol/MOESI_hammer-msg.sm b/src/mem/protocol/MOESI_hammer-msg.sm new file mode 100644 index 000000000..5d8226eb6 --- /dev/null +++ b/src/mem/protocol/MOESI_hammer-msg.sm @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * AMD's contributions to the MOESI hammer protocol do not constitute an + * endorsement of its similarity to any AMD products. + */ + +// CoherenceRequestType +enumeration(CoherenceRequestType, desc="...") { + GETX, desc="Get eXclusive"; + GETS, desc="Get Shared"; + PUT, desc="Put Ownership"; + WB_ACK, desc="Writeback ack"; + WB_NACK, desc="Writeback neg. ack"; +} + +// CoherenceResponseType +enumeration(CoherenceResponseType, desc="...") { + ACK, desc="ACKnowledgment, responder does not have a copy"; + ACK_SHARED, desc="ACKnowledgment, responder has a shared copy"; + DATA, desc="Data, responder does not have a copy"; + DATA_SHARED, desc="Data, responder has a shared copy"; + DATA_EXCLUSIVE, desc="Data, responder was exclusive, gave us a copy, and they went to invalid"; + WB_CLEAN, desc="Clean writeback"; + WB_DIRTY, desc="Dirty writeback"; + WB_EXCLUSIVE_CLEAN, desc="Clean writeback of exclusive data"; + WB_EXCLUSIVE_DIRTY, desc="Dirty writeback of exclusive data"; + UNBLOCK, desc="Unblock"; + NULL, desc="Null value"; +} + +// TriggerType +enumeration(TriggerType, desc="...") { + ALL_ACKS, desc="See corresponding event"; + ALL_ACKS_NO_SHARERS, desc="See corresponding event"; +} + +// TriggerMsg +structure(TriggerMsg, desc="...", interface="Message") { + Address Address, desc="Physical address for this request"; + TriggerType Type, desc="Type of trigger"; +} + +// RequestMsg (and also forwarded requests) +structure(RequestMsg, desc="...", interface="NetworkMessage") { + Address Address, desc="Physical address for this request"; + CoherenceRequestType Type, desc="Type of request (GetS, GetX, PutX, etc)"; + MachineID Requestor, desc="Node who initiated the request"; + NetDest Destination, desc="Multicast destination mask"; + MessageSizeType MessageSize, desc="size category of the message"; +} + +// ResponseMsg (and also unblock requests) +structure(ResponseMsg, desc="...", interface="NetworkMessage") { + Address Address, desc="Physical address for this request"; + CoherenceResponseType Type, desc="Type of response (Ack, Data, etc)"; + MachineID Sender, desc="Node who sent the data"; + NetDest Destination, desc="Node to whom the data is sent"; + DataBlock DataBlk, desc="data for the cache line"; + bool Dirty, desc="Is the data dirty (different than memory)?"; + int Acks, desc="How many messages this counts as"; + MessageSizeType MessageSize, desc="size category of the message"; +} + +enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") { + READ, desc="Memory Read"; + WRITE, desc="Memory Write"; + NULL, desc="Invalid"; +} + +enumeration(DMAResponseType, desc="...", default="DMAResponseType_NULL") { + DATA, desc="DATA read"; + ACK, desc="ACK write"; + NULL, desc="Invalid"; +} + +structure(DMARequestMsg, desc="...", interface="NetworkMessage") { + DMARequestType Type, desc="Request type (read/write)"; + Address PhysicalAddress, desc="Physical address for this request"; + Address LineAddress, desc="Line address for this request"; + MachineID Requestor, desc="Node who initiated the request"; + NetDest Destination, desc="Destination"; + DataBlock DataBlk, desc="DataBlk attached to this request"; + int Len, desc="The length of the request"; + MessageSizeType MessageSize, desc="size category of the message"; +} + +structure(DMAResponseMsg, desc="...", interface="NetworkMessage") { + DMAResponseType Type, desc="Response type (DATA/ACK)"; + Address PhysicalAddress, desc="Physical address for this request"; + Address LineAddress, desc="Line address for this request"; + NetDest Destination, desc="Destination"; + DataBlock DataBlk, desc="DataBlk attached to this request"; + MessageSizeType MessageSize, desc="size category of the message"; +} diff --git a/src/mem/protocol/MOESI_hammer.slicc b/src/mem/protocol/MOESI_hammer.slicc new file mode 100644 index 000000000..31ad47c2e --- /dev/null +++ b/src/mem/protocol/MOESI_hammer.slicc @@ -0,0 +1,5 @@ +MOESI_hammer-msg.sm +MOESI_hammer-cache.sm +MOESI_hammer-dir.sm +MOESI_hammer-dma.sm +standard_1level_CMP-protocol.sm diff --git a/src/mem/protocol/RubySlicc_ComponentMapping.sm b/src/mem/protocol/RubySlicc_ComponentMapping.sm index 0da1a05e2..891820c46 100644 --- a/src/mem/protocol/RubySlicc_ComponentMapping.sm +++ b/src/mem/protocol/RubySlicc_ComponentMapping.sm @@ -29,6 +29,8 @@ // Mapping functions +int getNumberOfLastLevelCaches(); + // NodeID map_address_to_node(Address addr); MachineID mapAddressToRange(Address addr, MachineType type, int low, int high); NetDest broadcast(MachineType type); diff --git a/src/mem/protocol/RubySlicc_Util.sm b/src/mem/protocol/RubySlicc_Util.sm index 312682bd7..e1771448f 100644 --- a/src/mem/protocol/RubySlicc_Util.sm +++ b/src/mem/protocol/RubySlicc_Util.sm @@ -52,7 +52,6 @@ void dirProfileCoherenceRequest(NodeID node, bool needCLB); bool isPerfectProtocol(); bool L1trainsPrefetcher(); int max_tokens(); -int N_tokens(); bool distributedPersistentEnabled(); Address setOffset(Address addr, int offset); Address makeLineAddress(Address addr); diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript index 293346f13..cd9920d22 100644 --- a/src/mem/protocol/SConscript +++ b/src/mem/protocol/SConscript @@ -29,30 +29,51 @@ # Authors: Nathan Binkert import os -import re -import string import sys -from os.path import basename, dirname, exists, expanduser, isdir, isfile -from os.path import join as joinpath - -import SCons +from os.path import isdir, isfile, join as joinpath Import('*') if not env['RUBY']: Return() -slicc_dir = Dir('../slicc') protocol_dir = Dir('.') html_dir = Dir('html') +slicc_dir = Dir('../slicc') + +sys.path[1:1] = [ Dir('..').srcnode().abspath ] +from slicc.parser import SLICC + +slicc_depends = [] +for root,dirs,files in os.walk(slicc_dir.srcnode().abspath): + for f in files: + if f.endswith('.py'): + slicc_depends.append(File(joinpath(root, f))) # # Use SLICC # -def slicc_generator(target, source, env, for_signature): - slicc_bin = str(source[0]) - protocol = source[1].get_contents() + +def slicc_scanner(node, env, path): + contents = node.get_contents() + files = [ line.strip() for line in contents.splitlines() ] + return files + +env.Append(SCANNERS=Scanner(function=slicc_scanner,skeys=['.slicc'])) + +def slicc_emitter(target, source, env): + files = [s.srcnode().abspath for s in source[1:]] + slicc = SLICC(debug=True) + print "SLICC parsing..." + for name in slicc.load(files, verbose=True): + print " %s" % name + + target.extend(sorted(slicc.files())) + return target, source + +def slicc_action(target, source, env): + protocol = source[0].get_contents() pdir = str(protocol_dir) hdir = str(html_dir) @@ -61,32 +82,31 @@ def slicc_generator(target, source, env, for_signature): if not isdir(hdir): os.mkdir(hdir) - do_html = "html" - cmdline = [ slicc_bin, pdir, hdir, protocol, do_html ] - cmdline += [ str(s) for s in source[2:] ] - cmdline = ' '.join(cmdline) - return cmdline + slicc = SLICC(debug=True) + files = [str(s) for s in source[1:]] + slicc.load(files, verbose=False) -slicc_builder = Builder(generator=slicc_generator) + print "SLICC Generator pass 1..." + slicc.findMachines() -protocol = env['PROTOCOL'] -sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"), - protocol_dir.File("%s.slicc" % protocol) ] + print "SLICC Generator pass 2..." + slicc.generate() -sys.path[0:0] = [env['ENV']['M5_PLY']] -execfile(slicc_dir.File('parser/parser.py').srcnode().abspath) + print "SLICC writing C++ files..." + slicc.writeCodeFiles(pdir) -sm_files = read_slicc([s.srcnode().abspath for s in sources]) -sm_files = [ protocol_dir.File(f) for f in sm_files ] + print "SLICC writing HTML files..." + slicc.writeHTMLFiles(hdir) -hh, cc = scan([s.srcnode().abspath for s in sm_files]) -hh = [ protocol_dir.File(f) for f in hh ] -cc = [ protocol_dir.File(f) for f in cc ] +slicc_builder = Builder(action=slicc_action, emitter=slicc_emitter) -slicc_bin = slicc_dir.File("slicc") +protocol = env['PROTOCOL'] +sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"), + protocol_dir.File("%s.slicc" % protocol) ] env.Append(BUILDERS={'SLICC' : slicc_builder}) -env.SLICC(hh + cc, [ slicc_bin, Value(protocol) ] + sm_files) +nodes = env.SLICC([], [ Value(protocol) ] + sources) +env.Depends(nodes, slicc_depends) -for f in cc: +for f in sorted(s for s in nodes if str(s).endswith('.cc')): Source(f) diff --git a/src/mem/protocol/SConsopts b/src/mem/protocol/SConsopts index ded0814d2..10a303681 100644 --- a/src/mem/protocol/SConsopts +++ b/src/mem/protocol/SConsopts @@ -47,9 +47,10 @@ all_protocols = [ 'MOSI_SMP_bcast_m', 'MOSI_SMP_directory_1level', 'MSI_MOSI_CMP_directory', + 'MOESI_hammer', ] -opt = EnumVariable('PROTOCOL', 'Coherence Protocol for Ruby', 'MI_example', +opt = EnumVariable('PROTOCOL', 'Coherence Protocol for Ruby', 'MOESI_CMP_directory', all_protocols) sticky_vars.AddVariables(opt) diff --git a/src/mem/request.hh b/src/mem/request.hh index c8c31ffcd..f2cc4647c 100644 --- a/src/mem/request.hh +++ b/src/mem/request.hh @@ -72,8 +72,6 @@ class Request : public FastAlloc /** This request is to a memory mapped register. */ static const FlagsType MMAPED_IPR = 0x00002000; - /** The request should not cause a page fault. */ - static const FlagsType NO_FAULT = 0x00010000; /** The request should ignore unaligned access faults */ static const FlagsType NO_ALIGN_FAULT = 0x00020000; /** The request should ignore unaligned access faults */ diff --git a/src/mem/ruby/SConscript b/src/mem/ruby/SConscript index 0c8423c85..3559f042f 100644 --- a/src/mem/ruby/SConscript +++ b/src/mem/ruby/SConscript @@ -114,6 +114,7 @@ MakeInclude('system/MachineID.hh') MakeInclude('system/MemoryControl.hh') MakeInclude('system/NodeID.hh') MakeInclude('system/PerfectCacheMemory.hh') +MakeInclude('system/PersistentTable.hh') MakeInclude('system/Sequencer.hh') MakeInclude('system/TBETable.hh') MakeInclude('system/TimerTable.hh') diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc index 3928e94e6..d157e2a94 100644 --- a/src/mem/ruby/buffers/MessageBuffer.cc +++ b/src/mem/ruby/buffers/MessageBuffer.cc @@ -34,27 +34,7 @@ #include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/system/System.hh" -MessageBuffer::MessageBuffer() -{ - m_msg_counter = 0; - m_consumer_ptr = NULL; - m_ordering_set = false; - m_strict_fifo = true; - m_size = 0; - m_max_size = -1; - m_last_arrival_time = 0; - m_randomization = true; - m_size_last_time_size_checked = 0; - m_time_last_time_size_checked = 0; - m_time_last_time_enqueue = 0; - m_time_last_time_pop = 0; - m_size_at_cycle_start = 0; - m_msgs_this_cycle = 0; - m_not_avail_count = 0; - m_priority_rank = 0; -} - -MessageBuffer::MessageBuffer(const Chip* chip_ptr) // The chip_ptr is ignored, but could be used for extra debugging +MessageBuffer::MessageBuffer(const string &name) { m_msg_counter = 0; m_consumer_ptr = NULL; @@ -72,6 +52,7 @@ MessageBuffer::MessageBuffer(const Chip* chip_ptr) // The chip_ptr is ignored, m_msgs_this_cycle = 0; m_not_avail_count = 0; m_priority_rank = 0; + m_name = name; } int MessageBuffer::getSize() diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh index 3ca6790d0..8440c3335 100644 --- a/src/mem/ruby/buffers/MessageBuffer.hh +++ b/src/mem/ruby/buffers/MessageBuffer.hh @@ -46,15 +46,11 @@ #include "mem/gems_common/PrioHeap.hh" #include "mem/gems_common/util.hh" -class Chip; - class MessageBuffer { public: // Constructors - MessageBuffer(); - MessageBuffer(const Chip* chip_ptr); // The chip_ptr is ignored, but could be used for extra debugging + MessageBuffer(const string &name = ""); - // Use Default Destructor // ~MessageBuffer() // Public Methods diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh index c48152354..88cd2668a 100644 --- a/src/mem/ruby/common/Address.hh +++ b/src/mem/ruby/common/Address.hh @@ -148,7 +148,7 @@ inline physical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive { physical_address_t mask; - assert(big >= small); + assert((unsigned)big >= (unsigned)small); if (big >= ADDRESS_WIDTH - 1) { return (m_address >> small); diff --git a/src/mem/ruby/common/DataBlock.hh b/src/mem/ruby/common/DataBlock.hh index 3c8ef56f4..1d399753e 100644 --- a/src/mem/ruby/common/DataBlock.hh +++ b/src/mem/ruby/common/DataBlock.hh @@ -45,7 +45,11 @@ class DataBlock { } // Destructor - ~DataBlock() { if(m_alloc) delete [] m_data;} + ~DataBlock() { + if(m_alloc) { + delete [] m_data; + } + } DataBlock& operator=(const DataBlock& obj); diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc index 1115152f4..cb9fdf082 100644 --- a/src/mem/ruby/common/Debug.cc +++ b/src/mem/ruby/common/Debug.cc @@ -39,6 +39,7 @@ #include "mem/ruby/common/Debug.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/gems_common/util.hh" +#include "base/misc.hh" class Debug; extern Debug* g_debug_ptr; @@ -70,6 +71,7 @@ DebugComponentData debugComponents[] = {"Cache", 'c' }, {"Predictor", 'p' }, {"Allocator", 'a' }, + {"Memory", 'M' }, }; extern "C" void changeDebugVerbosity(VerbosityLevel vb); @@ -95,19 +97,27 @@ Debug::Debug() Debug::Debug( const string & name, const vector<string> & argv ) { - for (size_t i=0;i<argv.size();i+=2){ - if (argv[i] == "filter_string") - setFilterString( argv[i+1].c_str() ); - else if (argv[i] == "verbosity_string") + // + // must clear the filter before adding filter strings + // + clearFilter(); + + for (size_t i=0;i<argv.size();i+=2) { + if (argv[i] == "filter_string") { + if (setFilterString(argv[i+1].c_str())) { + fatal("could not set filter string to %s\n", argv[i+1].c_str()); + } + } else if (argv[i] == "verbosity_string") { setVerbosityString( argv[i+1].c_str() ); - else if (argv[i] == "start_time") + } else if (argv[i] == "start_time") { m_starting_cycle = atoi( argv[i+1].c_str() ); - else if (argv[i] == "output_filename") + } else if (argv[i] == "output_filename") { setDebugOutputFile( argv[i+1].c_str() ); - else if (argv[i] == "protocol_trace") + } else if (argv[i] == "protocol_trace") { m_protocol_trace = string_to_bool(argv[i+1]); - else - assert(0); + } else { + fatal("invalid argument %s\n"); + } } } @@ -119,7 +129,8 @@ Debug::Debug( const char *filterString, const char *verboseString, debug_cout_ptr = &cout; m_starting_cycle = filterStartTime; - setFilterString( filterString ); + if (setFilterString(filterString)) + fatal("could not set filter string to %s\n", filterString); setVerbosityString( verboseString ); setDebugOutputFile( filename ); } diff --git a/src/mem/ruby/common/Debug.hh b/src/mem/ruby/common/Debug.hh index c038d57c2..03e123866 100644 --- a/src/mem/ruby/common/Debug.hh +++ b/src/mem/ruby/common/Debug.hh @@ -63,6 +63,7 @@ enum DebugComponents CACHE_COMP, PREDICTOR_COMP, ALLOCATOR_COMP, + MEMORY_COMP, NUMBER_OF_COMPS }; diff --git a/src/mem/ruby/common/NetDest.cc b/src/mem/ruby/common/NetDest.cc index 32771235f..35bb4ec43 100644 --- a/src/mem/ruby/common/NetDest.cc +++ b/src/mem/ruby/common/NetDest.cc @@ -133,13 +133,14 @@ NodeID NetDest::elementAt(MachineID index) { return m_bits[vecIndex(index)].elementAt(bitIndex(index.num)); } -NodeID NetDest::smallestElement() const +MachineID NetDest::smallestElement() const { assert(count() > 0); for (int i=0; i<m_bits.size(); i++) { for (int j=0; j<m_bits[i].getSize(); j++) { if (m_bits[i].isElement(j)) { - return j; + MachineID mach = {MachineType_from_base_level(i), j}; + return mach; } } } diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh index 1dcee7b7a..071106623 100644 --- a/src/mem/ruby/common/NetDest.hh +++ b/src/mem/ruby/common/NetDest.hh @@ -63,7 +63,7 @@ public: NetDest& operator=(const Set& obj); // Destructor - // ~NetDest(); + ~NetDest() { DEBUG_MSG(MEMORY_COMP, LowPrio, "NetDest Destructor"); } // Public Methods void add(MachineID newElement); @@ -96,7 +96,7 @@ public: //For Princeton Network Vector<NodeID> getAllDest(); - NodeID smallestElement() const; + MachineID smallestElement() const; MachineID smallestElement(MachineType machine) const; void setSize(); diff --git a/src/mem/ruby/config/MI_example-homogeneous.rb b/src/mem/ruby/config/MI_example-homogeneous.rb index 409d0fe3a..71e20c318 100644 --- a/src/mem/ruby/config/MI_example-homogeneous.rb +++ b/src/mem/ruby/config/MI_example-homogeneous.rb @@ -13,7 +13,7 @@ RubySystem.reset # default values num_cores = 2 -l1_cache_size_kb = 32 +l1_cache_size_kb = 32768 l1_cache_assoc = 8 l1_cache_latency = 1 num_memories = 2 @@ -44,6 +44,15 @@ for i in 0..$*.size-1 do elsif $*[i] == "-s" memory_size_mb = $*[i+1].to_i i = i + 1 + elsif $*[i] == "-C" + l1_cache_size_bytes = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-A" + l1_cache_assoc = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-D" + num_dma = $*[i+1].to_i + i = i + 1 end end @@ -55,7 +64,7 @@ assert(protocol == "MI_example", __FILE__ + " cannot be used with protocol " + p require protocol+".rb" num_cores.times { |n| - cache = SetAssociativeCache.new("l1u_"+n.to_s, l1_cache_size_kb, l1_cache_latency, l1_cache_assoc, "PSEUDO_LRU") + cache = SetAssociativeCache.new("l1u_"+n.to_s, l1_cache_size_bytes, l1_cache_latency, l1_cache_assoc, "PSEUDO_LRU") sequencer = Sequencer.new("Sequencer_"+n.to_s, cache, cache) iface_ports << sequencer net_ports << MI_example_CacheController.new("L1CacheController_"+n.to_s, diff --git a/src/mem/ruby/config/MI_example.rb b/src/mem/ruby/config/MI_example.rb index 187dc7a68..8113087aa 100644 --- a/src/mem/ruby/config/MI_example.rb +++ b/src/mem/ruby/config/MI_example.rb @@ -23,8 +23,6 @@ class MI_example_DirectoryController < DirectoryController def argv() vec = super() vec += " directory_latency "+directory_latency.to_s - vec += " dma_select_low_bit "+log_int(RubySystem.block_size_bytes).to_s - vec += " dma_select_num_bits "+log_int(NetPort.totalOfType("DMA")).to_s end end diff --git a/src/mem/ruby/config/MOESI_CMP_token.rb b/src/mem/ruby/config/MOESI_CMP_token.rb new file mode 100644 index 000000000..ba963dc06 --- /dev/null +++ b/src/mem/ruby/config/MOESI_CMP_token.rb @@ -0,0 +1,92 @@ + +require "cfg.rb" +require "util.rb" + + +class MOESI_CMP_token_L1CacheController < L1CacheController + attr :icache, :dcache + attr :num_l2_controllers + attr :n_tokens + def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers, n_tokens) + super(obj_name, mach_type, [icache, dcache], sequencer) + @icache = icache + @dcache = dcache + @num_l2_controllers = num_l2_controllers + @n_tokens = n_tokens + end + def argv() + num_select_bits = log_int(num_l2_controllers) + num_block_bits = log_int(RubySystem.block_size_bytes) + + l2_select_low_bit = num_block_bits + + vec = super() + vec += " icache " + @icache.obj_name + vec += " dcache " + @dcache.obj_name + vec += " l1_request_latency " + l1_request_latency.to_s + vec += " l1_response_latency " + l1_response_latency.to_s + vec += " l2_select_low_bit " + l2_select_low_bit.to_s + vec += " l2_select_num_bits " + num_select_bits.to_s + vec += " N_tokens " + n_tokens.to_s + vec += " retry_threshold " + retry_threshold.to_s + vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s + vec += " dynamic_timeout_enabled " + dynamic_timeout_enabled.to_s + + return vec + end +end + +class MOESI_CMP_token_L2CacheController < CacheController + attr :cache + attr :n_tokens + def initialize(obj_name, mach_type, cache, n_tokens) + super(obj_name, mach_type, [cache]) + @cache = cache + @n_tokens = n_tokens + end + def argv() + vec = super() + vec += " cache " + @cache.obj_name + vec += " l2_request_latency " + l2_request_latency.to_s + vec += " l2_response_latency " + l2_response_latency.to_s + vec += " N_tokens " + n_tokens.to_s + vec += " filtering_enabled " + filtering_enabled.to_s + return vec + end +end + + +class MOESI_CMP_token_DirectoryController < DirectoryController + attr :num_l2_controllers + def initialize(obj_name, mach_type, directory, memory_control, num_l2_controllers) + super(obj_name, mach_type, directory, memory_control) + @num_l2_controllers = num_l2_controllers + end + def argv() + num_select_bits = log_int(num_l2_controllers) + num_block_bits = log_int(RubySystem.block_size_bytes) + + l2_select_low_bit = num_block_bits + + vec = super() + vec += " directory_latency "+directory_latency.to_s + vec += " l2_select_low_bit " + l2_select_low_bit.to_s + vec += " l2_select_num_bits " + num_select_bits.to_s + vec += " distributed_persistent "+distributed_persistent.to_s + vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s + return vec + end + +end + +class MOESI_CMP_token_DMAController < DMAController + def initialize(obj_name, mach_type, dma_sequencer) + super(obj_name, mach_type, dma_sequencer) + end + def argv() + vec = super + vec += " request_latency "+request_latency.to_s + vec += " response_latency "+response_latency.to_s + return vec + end +end diff --git a/src/mem/ruby/config/MOESI_hammer-homogeneous.rb b/src/mem/ruby/config/MOESI_hammer-homogeneous.rb new file mode 100644 index 000000000..02af0ec27 --- /dev/null +++ b/src/mem/ruby/config/MOESI_hammer-homogeneous.rb @@ -0,0 +1,109 @@ +#!/usr/bin/ruby +# +# Creates multiple on-chip nodes with three level of cache. +# + +require "cfg.rb" + +RubySystem.reset + +# default values + +num_cores = 2 +l1_cache_size_bytes = 32768 +l1_cache_assoc = 2 +l1_cache_latency = 3 +l2_cache_size_bytes = 1048576 +l2_cache_assoc = 16 +l2_cache_latency = 15 +num_memories = 2 +memory_size_mb = 1024 +num_dma = 0 +use_map = false +map_levels = 4 +protocol = "MOESI_hammer" + +# check for overrides + + +for i in 0..$*.size-1 do + if $*[i] == "-c" + protocol = $*[i+1] + i = i+1 + elsif $*[i] == "-p" + num_cores = $*[i+1].to_i + i = i+1 + elsif $*[i] == "-m" + num_memories = $*[i+1].to_i + i = i+1 + elsif $*[i] == "-s" + memory_size_mb = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-U" + use_map = $*[i+1] + i = i + 1 + elsif $*[i] == "-C" + l1_cache_size_bytes = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-A" + l1_cache_assoc = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-M" + map_levels = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-D" + num_dma = $*[i+1].to_i + i = i + 1 + end +end + +net_ports = Array.new +iface_ports = Array.new + +assert(protocol == "MOESI_hammer", __FILE__ + " cannot be used with protocol " + protocol) + +require protocol+".rb" + +num_cores.times { |n| + icache = SetAssociativeCache.new("l1i_"+n.to_s, + l1_cache_size_bytes, + l1_cache_latency, + l1_cache_assoc, + "PSEUDO_LRU") + dcache = SetAssociativeCache.new("l1d_"+n.to_s, + l1_cache_size_bytes, + l1_cache_latency, + l1_cache_assoc, + "PSEUDO_LRU") + l2cache = SetAssociativeCache.new("l2u_"+n.to_s, + l2_cache_size_bytes, + l2_cache_latency, + l2_cache_assoc, + "PSEUDO_LRU") + sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache) + iface_ports << sequencer + net_ports << MOESI_hammer_CacheController.new("L1CacheController_"+n.to_s, + "L1Cache", + icache, + dcache, + l2cache, + sequencer) +} +num_memories.times { |n| + directory = DirectoryMemory.new("DirectoryMemory_"+n.to_s, memory_size_mb/num_memories) + memory_control = MemoryControl.new("MemoryControl_"+n.to_s) + net_ports << MOESI_hammer_DirectoryController.new("DirectoryController_"+n.to_s, + "Directory", + directory, + memory_control) +} +num_dma.times { |n| + dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s) + iface_ports << dma_sequencer + net_ports << MOESI_hammer_DMAController.new("DMAController_"+n.to_s, "DMA", dma_sequencer) +} + +topology = CrossbarTopology.new("theTopology", net_ports) +on_chip_net = Network.new("theNetwork", topology) + +RubySystem.init(iface_ports, on_chip_net) diff --git a/src/mem/ruby/config/MOESI_hammer.rb b/src/mem/ruby/config/MOESI_hammer.rb new file mode 100644 index 000000000..d3735028b --- /dev/null +++ b/src/mem/ruby/config/MOESI_hammer.rb @@ -0,0 +1,41 @@ + +require "util.rb" + +class MOESI_hammer_CacheController < L1CacheController + attr :cache + def initialize(obj_name, mach_type, icache, dcache, l2cache, sequencer) + super(obj_name, mach_type, [icache, dcache, l2cache], sequencer) + @icache = icache + @dcache = dcache + @l2cache = l2cache + end + def argv() + vec = super() + vec += " icache " + @icache.obj_name + vec += " dcache " + @dcache.obj_name + vec += " l2cache " + @l2cache.obj_name + vec += " issue_latency "+issue_latency.to_s + vec += " cache_response_latency "+cache_response_latency.to_s + end + +end + +class MOESI_hammer_DirectoryController < DirectoryController + def initialize(obj_name, mach_type, directory, memory_control) + super(obj_name, mach_type, directory, memory_control) + end + def argv() + vec = super() + vec += " memory_controller_latency "+memory_controller_latency.to_s + end +end + +class MOESI_hammer_DMAController < DMAController + def initialize(obj_name, mach_type, dma_sequencer) + super(obj_name, mach_type, dma_sequencer) + end + def argv() + vec = super + vec += " request_latency "+request_latency.to_s + end +end diff --git a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb index a4a1982f4..a8ef1eceb 100644 --- a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb +++ b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb @@ -27,7 +27,7 @@ memory_size_mb = 1024 num_dma = 1 #default protocol -protocol = ""#"MESI_CMP_directory" +protocol = "MOESI_CMP_directory" # check for overrides diff --git a/src/mem/ruby/libruby.cc b/src/mem/ruby/libruby.cc index e4e302eba..b9a72d071 100644 --- a/src/mem/ruby/libruby.cc +++ b/src/mem/ruby/libruby.cc @@ -66,6 +66,12 @@ ostream& operator<<(ostream& out, const RubyRequestType& obj) return out; } +ostream& operator<<(std::ostream& out, const RubyRequest& obj) +{ + out << hex << "0x" << obj.paddr << flush; + return out; +} + vector<string> tokenizeString(string str, string delims) { vector<string> tokens; diff --git a/src/mem/ruby/libruby.hh b/src/mem/ruby/libruby.hh index 8f1aa8098..4c50611c1 100644 --- a/src/mem/ruby/libruby.hh +++ b/src/mem/ruby/libruby.hh @@ -39,6 +39,8 @@ struct RubyRequest { {} }; +std::ostream& operator<<(std::ostream& out, const RubyRequest& obj); + /** * Initialize the system. cfg_file is a Ruby-lang configuration script */ diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc index 984ec7ca8..ac785f632 100644 --- a/src/mem/ruby/network/Network.cc +++ b/src/mem/ruby/network/Network.cc @@ -1,3 +1,30 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "mem/protocol/MachineType.hh" #include "mem/ruby/network/Network.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh index 387ed0bc1..c554d7216 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh @@ -1,9 +1,33 @@ /* - * CreditLink_d.hh + * Copyright (c) 2008 Princeton University + * All rights reserved. * - * Niket Agarwal, Princeton University + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * - * */ + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal + */ + #ifndef CREDIT_LINK_D_H #define CREDIT_LINK_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc index 51393b576..df643e800 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * GarnetNetwork_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh" #include "mem/protocol/MachineType.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh index f4b809443..997f5e374 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * GarnetNetwork_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef GARNETNETWORK_D_H #define GARNETNETWORK_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc index 0ae32de13..7f344b0b7 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InputUnit_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh index a59ac89d8..beee79b3e 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InputUnit_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef INPUT_UNIT_D_H #define INPUT_UNIT_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh index a69dbf107..62ed9a12c 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * NetworkHeader.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef NETWORK_HEADER_H #define NETWORK_HEADER_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc index 3377ffd1d..c31b76d62 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * NetworkInterface_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh" #include "mem/ruby/buffers/MessageBuffer.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh index 625226254..12b8d57e1 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * NetworkInterface_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef NET_INTERFACE_D_H #define NET_INTERFACE_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc index 8382d331f..dc3c73b0c 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * NetworkLink_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh index 90fb9f6dc..fed8afbd3 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * NetworkLink_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef NETWORK_LINK_D_H #define NETWORK_LINK_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc index 69e3ae377..42d9af861 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutVCState_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh index dc64b8504..fe6b5fc79 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutVCState_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef OUT_VC_STATE_D_H #define OUT_VC_STATE_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc index eb2450897..e672009c9 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutputUnit_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh index 78f46d1b5..beeab8c7f 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutputUnit_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef OUTPUT_UNIT_D_H #define OUTPUT_UNIT_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc index 161e6ecff..5334de7b9 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Router_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh index 23a8681d9..f9af1abfb 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * Router_d.hh - * - * Niket Agarwal, Princeton University - * - * */ #ifndef ROUTER_D_H #define ROUTER_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc index 488741055..9f12ac9cc 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Routingunit_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh index 091ee90ef..33c9f3cc4 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Routerunit_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef ROUTING_UNIT_D_H #define ROUTING_UNIT_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc index dd0378305..c7308597a 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * SWallocator_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh index b1867df7f..f0ec5d77e 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * SWallocator_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef SW_ALLOCATOR_D_H #define SW_ALLOCATOR_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc index e1ca64864..11a196906 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Switch_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh index 2e2f524a0..936972714 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Switch_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef SWITCH_D_H #define SWITCH_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc index 810aea175..4150907d1 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VCallocator_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" #include "mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh index 41e317bff..ad3c2c95f 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VCallocator_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef VC_ALLOCATOR_D_H #define VC_ALLOCATOR_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc index 2e4473a29..5ce3ca4e5 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VirtualChannel_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh index 4ac1898e2..2d81cb7e3 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VirtualChannel_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef VIRTUAL_CHANNEL_D_H #define VIRTUAL_CHANNEL_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc index f3ddca0f2..fa189a8cc 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * flitBuffer_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh index 70a47d5f6..2edea9d76 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * flitBuffer_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef FLIT_BUFFER_D_H #define FLIT_BUFFER_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc index 3defb8029..15e0b0394 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * flit_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/flit_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh index 6f64f4940..39f04052d 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * flit_d.hh * - * Niket Agarwal, Princeton University - * - * */ - + * Authors: Niket Agarwal + */ #ifndef FLIT_D_H #define FLIT_D_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh b/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh index f8bf6b949..82179ec21 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * FlexibleConsumer.hh - * - * Niket Agarwal, Princeton University - * - * */ #ifndef FLEXIBLE_CONSUMER_H #define FLEXIBLE_CONSUMER_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc index e56f5b5e8..5a6b610f9 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * GarnetNetwork.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh" #include "mem/protocol/MachineType.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh index 194fef778..c0e4ac6e4 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * GarnetNetwork.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef GARNET_NETWORK_H #define GARNET_NETWORK_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc index cecaf867e..7fdff46b9 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InVCState.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/InVcState.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh index b7005efea..67ff6b459 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* * - * InVCState.hh - * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef IN_VC_STATE_H #define IN_VC_STATE_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh index 0a450c002..2080ef022 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,16 +24,14 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ /* - * NetworkConfig.hh - * - * Description: This header file is used to define all configuration parameters required by the interconnection network. - * - * Niket Agarwal, Princeton University - * - * */ + * This header file is used to define all configuration parameters + * required by the interconnection network. + */ #ifndef NETWORKCONFIG_H #define NETWORKCONFIG_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc index 597c942b7..4af5b296f 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * NetworkInterface.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh" #include "mem/ruby/buffers/MessageBuffer.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh index af4b1d4eb..8444658ea 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkInterface.hh - * - * Niket Agarwal, Princeton University - * - * */ #ifndef NET_INTERFACE_H #define NET_INTERFACE_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc index ddc92d44c..598c9e2a4 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * NetworkLink.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh index 6cc35b39d..9f5640a2e 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkLink.hh - * - * Niket Agarwal, Princeton University - * - * */ #ifndef NETWORK_LINK_H #define NETWORK_LINK_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc index 9a95971eb..a00dd19c1 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutVCState.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh index cb05826dc..ba68bf2db 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutVCState.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef OUT_VC_STATE_H #define OUT_VC_STATE_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc index ea32e938d..628f19349 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Router.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/Router.hh" #include "mem/ruby/slicc_interface/NetworkMessage.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh b/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh index f3cf0036d..69d405ad4 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Router.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef ROUTER_H #define ROUTER_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc index 271d6dd38..9064cc4a2 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VCarbiter.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh" #include "mem/ruby/network/garnet-flexible-pipeline/Router.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh index 96a03b8dc..7f7e5e814 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VCarbiter.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef VC_ARBITER_H #define VC_ARBITER_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc b/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc index 51b8af6c6..549726348 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * flit.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/flit.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh index aeac2e63b..a2e628443 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * flit.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh" #include "mem/ruby/slicc_interface/Message.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc index a0bb71c9d..c68f8c78b 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * flitBuffer.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh index 006ba60bd..c722e161c 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * flitBuffer.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef FLIT_BUFFER_H #define FLIT_BUFFER_H diff --git a/src/mem/ruby/network/orion/power_utils.cc b/src/mem/ruby/network/orion/power_utils.cc index bc69c3cc7..358e13c6f 100644 --- a/src/mem/ruby/network/orion/power_utils.cc +++ b/src/mem/ruby/network/orion/power_utils.cc @@ -30,6 +30,7 @@ #include <cmath> #include <cstdio> +#include "base/types.hh" #include "mem/ruby/network/orion/parm_technology.hh" #include "mem/ruby/network/orion/power_utils.hh" @@ -39,11 +40,11 @@ static char h_tab[256] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; -static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long int new_val, unsigned long int mask ) +static uint32_t SIM_power_Hamming_slow( uint64_t old_val, uint64_t new_val, uint64_t mask ) { /* old slow code, I don't understand the new fast code though */ - /* unsigned long int dist; - unsigned Hamming = 0; + /* uint64_t dist; + uint32_t Hamming = 0; dist = ( old_val ^ new_val ) & mask; mask = (mask >> 1) + 1; @@ -58,7 +59,7 @@ static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long #define TWO(k) (BIGONE << (k)) #define CYCL(k) (BIGNONE/(1 + (TWO(TWO(k))))) #define BSUM(x,k) ((x)+=(x) >> TWO(k), (x) &= CYCL(k)) - unsigned long int x; + uint64_t x; x = (old_val ^ new_val) & mask; x = (x & CYCL(0)) + ((x>>TWO(0)) & CYCL(0)); @@ -74,7 +75,7 @@ static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long int SIM_power_init(void) { - unsigned i; + uint32_t i; /* initialize Hamming distance table */ for (i = 0; i < 256; i++) @@ -84,14 +85,16 @@ int SIM_power_init(void) } -/* assume unsigned long int is unsigned64_t */ -unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val, unsigned long int mask) + +uint32_t +SIM_power_Hamming(uint64_t old_val, uint64_t new_val, uint64_t mask) { - union { - unsigned long int x; - char id[8]; - } u; - unsigned rval; + union { + uint64_t x; + uint64_t id[8]; + } u; + + uint32_t rval; u.x = (old_val ^ new_val) & mask; @@ -108,10 +111,12 @@ unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val, } -unsigned SIM_power_Hamming_group(unsigned long int d1_new, unsigned long int d1_old, unsigned long int d2_new, unsigned long int d2_old, unsigned width, unsigned n_grp) +uint32_t +SIM_power_Hamming_group(uint64_t d1_new, uint64_t d1_old, uint64_t d2_new, + uint64_t d2_old, uint32_t width, uint32_t n_grp) { - unsigned rval = 0; - unsigned long int g1_new, g1_old, g2_new, g2_old, mask; + uint32_t rval = 0; + uint64_t g1_new, g1_old, g2_new, g2_old, mask; mask = HAMM_MASK(width); @@ -146,11 +151,12 @@ double logtwo(double x) return log10(x)/log10(2); } -unsigned SIM_power_logtwo(unsigned long int x) +uint32_t +SIM_power_logtwo(uint64_t x) { - unsigned rval = 0; + uint32_t rval = 0; - while (x >> rval && rval < sizeof(unsigned long int) << 3) rval++; + while (x >> rval && rval < sizeof(uint64_t) << 3) rval++; if (x == (BIGONE << rval - 1)) rval--; return rval; diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc index 497c602d1..adf7ee21e 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.cc +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc @@ -87,8 +87,10 @@ void SimpleNetwork::init(const vector<string> & argv) m_toNetQueues[node].setSize(m_virtual_networks); m_fromNetQueues[node].setSize(m_virtual_networks); for (int j = 0; j < m_virtual_networks; j++) { - m_toNetQueues[node][j] = new MessageBuffer; - m_fromNetQueues[node][j] = new MessageBuffer; + m_toNetQueues[node][j] = new MessageBuffer( + "toNet node "+int_to_string(node)+" j "+int_to_string(j)); + m_fromNetQueues[node][j] = new MessageBuffer( + "fromNet node "+int_to_string(node)+" j "+int_to_string(j)); } } @@ -124,7 +126,7 @@ SimpleNetwork::~SimpleNetwork() } m_switch_ptr_vector.deletePointers(); m_buffers_to_free.deletePointers(); - delete m_topology_ptr; + // delete m_topology_ptr; } // From a switch to an endpoint node diff --git a/src/mem/slicc/ast/DeclAST.cc b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc index 6ccf9a9d6..4d37b0007 100644 --- a/src/mem/slicc/ast/DeclAST.cc +++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc @@ -27,13 +27,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * DeclAST.C - * - * Description: See DeclAST.hh - * - * $Id$ - * - */ -#include "mem/slicc/ast/DeclAST.hh" +#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" +#include "mem/ruby/system/CacheMemory.hh" + +int getNumberOfLastLevelCaches() +{ + return CacheMemory::numberOfLastLevelCaches(); +} + diff --git a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh index 159c33815..69424c414 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh @@ -61,6 +61,15 @@ #define MACHINETYPE_L3CACHE_ENUM MachineType_NUM #endif +#ifdef MACHINETYPE_DMA +#define MACHINETYPE_DMA_ENUM MachineType_DMA +#else +#define MACHINETYPE_DMA_ENUM MachineType_NUM +#endif + +// used to determine the number of acks to wait for +int getNumberOfLastLevelCaches(); + // used to determine the home directory // returns a value between 0 and total_directories_within_the_system inline @@ -81,7 +90,7 @@ MachineID map_Address_to_Directory(const Address &addr) inline MachineID map_Address_to_DMA(const Address & addr) { - MachineID dma = {MachineType_DMA, 0}; + MachineID dma = {MACHINETYPE_DMA_ENUM, 0}; return dma; } diff --git a/src/mem/ruby/slicc_interface/SConscript b/src/mem/ruby/slicc_interface/SConscript index 2b20892ba..6ba614fa9 100644 --- a/src/mem/ruby/slicc_interface/SConscript +++ b/src/mem/ruby/slicc_interface/SConscript @@ -35,3 +35,4 @@ if not env['RUBY']: Source('AbstractCacheEntry.cc') Source('RubySlicc_Profiler_interface.cc') +Source('RubySlicc_ComponentMapping.cc') diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc new file mode 100644 index 000000000..cf3e094ad --- /dev/null +++ b/src/mem/ruby/system/CacheMemory.cc @@ -0,0 +1,483 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mem/ruby/system/CacheMemory.hh" + +int CacheMemory::m_num_last_level_caches = 0; +MachineType CacheMemory::m_last_level_machine_type = MachineType_FIRST; + +// Output operator declaration +//ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj); + +// ******************* Definitions ******************* + +// Output operator definition +ostream& operator<<(ostream& out, const CacheMemory& obj) +{ + obj.print(out); + out << flush; + return out; +} + + +// **************************************************************** + +CacheMemory::CacheMemory(const string & name) + : m_cache_name(name) +{ + m_profiler_ptr = new CacheProfiler(name); +} + +void CacheMemory::init(const vector<string> & argv) +{ + int cache_size = -1; + string policy; + + m_num_last_level_caches = + MachineType_base_count(MachineType_FIRST); + m_controller = NULL; + for (uint32 i=0; i<argv.size(); i+=2) { + if (argv[i] == "size") { + cache_size = atoi(argv[i+1].c_str()); + } else if (argv[i] == "latency") { + m_latency = atoi(argv[i+1].c_str()); + } else if (argv[i] == "assoc") { + m_cache_assoc = atoi(argv[i+1].c_str()); + } else if (argv[i] == "replacement_policy") { + policy = argv[i+1]; + } else if (argv[i] == "controller") { + m_controller = RubySystem::getController(argv[i+1]); + if (m_last_level_machine_type < m_controller->getMachineType()) { + m_num_last_level_caches = + MachineType_base_count(m_controller->getMachineType()); + m_last_level_machine_type = + m_controller->getMachineType(); + } + } else { + cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << argv[i] << endl; + } + } + + int num_lines = cache_size/RubySystem::getBlockSizeBytes(); + m_cache_num_sets = num_lines / m_cache_assoc; + m_cache_num_set_bits = log_int(m_cache_num_sets); + assert(m_cache_num_set_bits > 0); + + if(policy == "PSEUDO_LRU") + m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); + else if (policy == "LRU") + m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc); + else + assert(false); + + m_cache.setSize(m_cache_num_sets); + m_locked.setSize(m_cache_num_sets); + for (int i = 0; i < m_cache_num_sets; i++) { + m_cache[i].setSize(m_cache_assoc); + m_locked[i].setSize(m_cache_assoc); + for (int j = 0; j < m_cache_assoc; j++) { + m_cache[i][j] = NULL; + m_locked[i][j] = -1; + } + } +} + +CacheMemory::~CacheMemory() +{ + if(m_replacementPolicy_ptr != NULL) + delete m_replacementPolicy_ptr; + delete m_profiler_ptr; + for (int i = 0; i < m_cache_num_sets; i++) { + for (int j = 0; j < m_cache_assoc; j++) { + delete m_cache[i][j]; + } + } +} + +int +CacheMemory::numberOfLastLevelCaches() +{ + return m_num_last_level_caches; +} + + +void CacheMemory::printConfig(ostream& out) +{ + out << "Cache config: " << m_cache_name << endl; + if (m_controller != NULL) + out << " controller: " << m_controller->getName() << endl; + out << " cache_associativity: " << m_cache_assoc << endl; + out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; + const int cache_num_sets = 1 << m_cache_num_set_bits; + out << " num_cache_sets: " << cache_num_sets << endl; + out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl; + out << " cache_set_size_Kbytes: " + << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl; + out << " cache_set_size_Mbytes: " + << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl; + out << " cache_size_bytes: " + << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl; + out << " cache_size_Kbytes: " + << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl; + out << " cache_size_Mbytes: " + << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl; +} + +// PRIVATE METHODS + +// convert a Address to its location in the cache +Index CacheMemory::addressToCacheSet(const Address& address) const +{ + assert(address == line_address(address)); + return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1); +} + +// Given a cache index: returns the index of the tag in a set. +// returns -1 if the tag is not found. +int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const +{ + assert(tag == line_address(tag)); + // search the set for the tags + m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); + if (it != m_tag_index.end()) + if (m_cache[cacheSet][it->second]->m_Permission != AccessPermission_NotPresent) + return it->second; + return -1; // Not found +} + +// Given a cache index: returns the index of the tag in a set. +// returns -1 if the tag is not found. +int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const +{ + assert(tag == line_address(tag)); + // search the set for the tags + m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); + if (it != m_tag_index.end()) + return it->second; + return -1; // Not found +} + +// PUBLIC METHODS +bool CacheMemory::tryCacheAccess(const Address& address, + CacheRequestType type, + DataBlock*& data_ptr) +{ + assert(address == line_address(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + if(loc != -1){ // Do we even have a tag match? + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; + m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); + data_ptr = &(entry->getDataBlk()); + + if(entry->m_Permission == AccessPermission_Read_Write) { + return true; + } + if ((entry->m_Permission == AccessPermission_Read_Only) && + (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { + return true; + } + // The line must not be accessible + } + data_ptr = NULL; + return false; +} + +bool CacheMemory::testCacheAccess(const Address& address, + CacheRequestType type, + DataBlock*& data_ptr) +{ + assert(address == line_address(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + if(loc != -1){ // Do we even have a tag match? + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; + m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); + data_ptr = &(entry->getDataBlk()); + + return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent); + } + data_ptr = NULL; + return false; +} + +// tests to see if an address is present in the cache +bool CacheMemory::isTagPresent(const Address& address) const +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int location = findTagInSet(cacheSet, address); + + if (location == -1) { + // We didn't find the tag + DEBUG_EXPR(CACHE_COMP, LowPrio, address); + DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match"); + return false; + } + DEBUG_EXPR(CACHE_COMP, LowPrio, address); + DEBUG_MSG(CACHE_COMP, LowPrio, "found"); + return true; +} + +// Returns true if there is: +// a) a tag match on this address or there is +// b) an unused line in the same cache "way" +bool CacheMemory::cacheAvail(const Address& address) const +{ + assert(address == line_address(address)); + + Index cacheSet = addressToCacheSet(address); + + for (int i=0; i < m_cache_assoc; i++) { + AbstractCacheEntry* entry = m_cache[cacheSet][i]; + if (entry != NULL) { + if (entry->m_Address == address || // Already in the cache + entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry + return true; + } + } else { + return true; + } + } + return false; +} + +void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) +{ + assert(address == line_address(address)); + assert(!isTagPresent(address)); + assert(cacheAvail(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + + // Find the first open slot + Index cacheSet = addressToCacheSet(address); + for (int i=0; i < m_cache_assoc; i++) { + if (m_cache[cacheSet][i] == NULL || + m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) { + m_cache[cacheSet][i] = entry; // Init entry + m_cache[cacheSet][i]->m_Address = address; + m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; + m_locked[cacheSet][i] = -1; + m_tag_index[address] = i; + + m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime()); + + return; + } + } + ERROR_MSG("Allocate didn't find an available entry"); +} + +void CacheMemory::deallocate(const Address& address) +{ + assert(address == line_address(address)); + assert(isTagPresent(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + Index cacheSet = addressToCacheSet(address); + int location = findTagInSet(cacheSet, address); + if (location != -1){ + delete m_cache[cacheSet][location]; + m_cache[cacheSet][location] = NULL; + m_locked[cacheSet][location] = -1; + m_tag_index.erase(address); + } +} + +// Returns with the physical address of the conflicting cache line +Address CacheMemory::cacheProbe(const Address& address) const +{ + assert(address == line_address(address)); + assert(!cacheAvail(address)); + + Index cacheSet = addressToCacheSet(address); + return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address; +} + +// looks an address up in the cache +AbstractCacheEntry& CacheMemory::lookup(const Address& address) +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + return *m_cache[cacheSet][loc]; +} + +// looks an address up in the cache +const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + return *m_cache[cacheSet][loc]; +} + +AccessPermission CacheMemory::getPermission(const Address& address) const +{ + assert(address == line_address(address)); + return lookup(address).m_Permission; +} + +void CacheMemory::changePermission(const Address& address, AccessPermission new_perm) +{ + assert(address == line_address(address)); + lookup(address).m_Permission = new_perm; + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + m_locked[cacheSet][loc] = -1; + assert(getPermission(address) == new_perm); +} + +// Sets the most recently used bit for a cache block +void CacheMemory::setMRU(const Address& address) +{ + Index cacheSet; + + cacheSet = addressToCacheSet(address); + m_replacementPolicy_ptr->touch(cacheSet, + findTagInSet(cacheSet, address), + g_eventQueue_ptr->getTime()); +} + +void CacheMemory::profileMiss(const CacheMsg & msg) +{ + m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(), + msg.getSize(), msg.getPrefetch()); +} + +void CacheMemory::recordCacheContents(CacheRecorder& tr) const +{ + for (int i = 0; i < m_cache_num_sets; i++) { + for (int j = 0; j < m_cache_assoc; j++) { + AccessPermission perm = m_cache[i][j]->m_Permission; + CacheRequestType request_type = CacheRequestType_NULL; + if (perm == AccessPermission_Read_Only) { + if (m_is_instruction_only_cache) { + request_type = CacheRequestType_IFETCH; + } else { + request_type = CacheRequestType_LD; + } + } else if (perm == AccessPermission_Read_Write) { + request_type = CacheRequestType_ST; + } + + if (request_type != CacheRequestType_NULL) { + // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, + // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j)); + } + } + } +} + +void CacheMemory::print(ostream& out) const +{ + out << "Cache dump: " << m_cache_name << endl; + for (int i = 0; i < m_cache_num_sets; i++) { + for (int j = 0; j < m_cache_assoc; j++) { + if (m_cache[i][j] != NULL) { + out << " Index: " << i + << " way: " << j + << " entry: " << *m_cache[i][j] << endl; + } else { + out << " Index: " << i + << " way: " << j + << " entry: NULL" << endl; + } + } + } +} + +void CacheMemory::printData(ostream& out) const +{ + out << "printData() not supported" << endl; +} + +void CacheMemory::clearStats() const +{ + m_profiler_ptr->clearStats(); +} + +void CacheMemory::printStats(ostream& out) const +{ + m_profiler_ptr->printStats(out); +} + +void CacheMemory::getMemoryValue(const Address& addr, char* value, + unsigned int size_in_bytes ){ + AbstractCacheEntry& entry = lookup(line_address(addr)); + unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); + for(unsigned int i=0; i<size_in_bytes; ++i){ + value[i] = entry.getDataBlk().getByte(i + startByte); + } +} + +void CacheMemory::setMemoryValue(const Address& addr, char* value, + unsigned int size_in_bytes ){ + AbstractCacheEntry& entry = lookup(line_address(addr)); + unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); + assert(size_in_bytes > 0); + for(unsigned int i=0; i<size_in_bytes; ++i){ + entry.getDataBlk().setByte(i + startByte, value[i]); + } + + // entry = lookup(line_address(addr)); +} + +void +CacheMemory::setLocked(const Address& address, int context) +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + m_locked[cacheSet][loc] = context; +} + +void +CacheMemory::clearLocked(const Address& address) +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + m_locked[cacheSet][loc] = -1; +} + +bool +CacheMemory::isLocked(const Address& address, int context) +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + return m_locked[cacheSet][loc] == context; +} + diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh index 7268189ea..8b84f33ec 100644 --- a/src/mem/ruby/system/CacheMemory.hh +++ b/src/mem/ruby/system/CacheMemory.hh @@ -54,6 +54,7 @@ #include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/profiler/CacheProfiler.hh" #include "mem/protocol/CacheMsg.hh" +#include "base/hashmap.hh" #include <vector> class CacheMemory { @@ -104,6 +105,8 @@ public: AccessPermission getPermission(const Address& address) const; void changePermission(const Address& address, AccessPermission new_perm); + static int numberOfLastLevelCaches(); + int getLatency() const { return m_latency; } // Hook for checkpointing the contents of the cache @@ -169,465 +172,11 @@ private: int m_cache_assoc; static Vector< CacheMemory* > m_all_caches; -}; + + static int m_num_last_level_caches; + static MachineType m_last_level_machine_type; -// Output operator declaration -//ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj); - -// ******************* Definitions ******************* - -// Output operator definition -inline -ostream& operator<<(ostream& out, const CacheMemory& obj) -{ - obj.print(out); - out << flush; - return out; -} - - -// **************************************************************** - -inline -CacheMemory::CacheMemory(const string & name) - : m_cache_name(name) -{ - m_profiler_ptr = new CacheProfiler(name); -} - -inline -void CacheMemory::init(const vector<string> & argv) -{ - int cache_size = 0; - string policy; - - m_controller = NULL; - for (uint32 i=0; i<argv.size(); i+=2) { - if (argv[i] == "size_kb") { - cache_size = atoi(argv[i+1].c_str()); - } else if (argv[i] == "latency") { - m_latency = atoi(argv[i+1].c_str()); - } else if (argv[i] == "assoc") { - m_cache_assoc = atoi(argv[i+1].c_str()); - } else if (argv[i] == "replacement_policy") { - policy = argv[i+1]; - } else if (argv[i] == "controller") { - m_controller = RubySystem::getController(argv[i+1]); - } else { - cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << argv[i] << endl; - } - } - - int num_lines = (cache_size*1024)/RubySystem::getBlockSizeBytes(); - m_cache_num_sets = num_lines / m_cache_assoc; - m_cache_num_set_bits = log_int(m_cache_num_sets); - - if(policy == "PSEUDO_LRU") - m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); - else if (policy == "LRU") - m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc); - else - assert(false); - - m_cache.setSize(m_cache_num_sets); - m_locked.setSize(m_cache_num_sets); - for (int i = 0; i < m_cache_num_sets; i++) { - m_cache[i].setSize(m_cache_assoc); - m_locked[i].setSize(m_cache_assoc); - for (int j = 0; j < m_cache_assoc; j++) { - m_cache[i][j] = NULL; - m_locked[i][j] = -1; - } - } -} - -inline -CacheMemory::~CacheMemory() -{ - if(m_replacementPolicy_ptr != NULL) - delete m_replacementPolicy_ptr; -} - -inline -void CacheMemory::printConfig(ostream& out) -{ - out << "Cache config: " << m_cache_name << endl; - if (m_controller != NULL) - out << " controller: " << m_controller->getName() << endl; - out << " cache_associativity: " << m_cache_assoc << endl; - out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; - const int cache_num_sets = 1 << m_cache_num_set_bits; - out << " num_cache_sets: " << cache_num_sets << endl; - out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl; - out << " cache_set_size_Kbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl; - out << " cache_set_size_Mbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl; - out << " cache_size_bytes: " - << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl; - out << " cache_size_Kbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl; - out << " cache_size_Mbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl; -} - -// PRIVATE METHODS - -// convert a Address to its location in the cache -inline -Index CacheMemory::addressToCacheSet(const Address& address) const -{ - assert(address == line_address(address)); - return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1); -} - -// Given a cache index: returns the index of the tag in a set. -// returns -1 if the tag is not found. -inline -int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const -{ - assert(tag == line_address(tag)); - // search the set for the tags - m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); - if (it != m_tag_index.end()) - if (m_cache[cacheSet][it->second]->m_Permission != AccessPermission_NotPresent) - return it->second; - return -1; // Not found -} - -// Given a cache index: returns the index of the tag in a set. -// returns -1 if the tag is not found. -inline -int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const -{ - assert(tag == line_address(tag)); - // search the set for the tags - m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag); - if (it != m_tag_index.end()) - return it->second; - return -1; // Not found -} - -// PUBLIC METHODS -inline -bool CacheMemory::tryCacheAccess(const Address& address, - CacheRequestType type, - DataBlock*& data_ptr) -{ - assert(address == line_address(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - if(loc != -1){ // Do we even have a tag match? - AbstractCacheEntry* entry = m_cache[cacheSet][loc]; - m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); - data_ptr = &(entry->getDataBlk()); - - if(entry->m_Permission == AccessPermission_Read_Write) { - return true; - } - if ((entry->m_Permission == AccessPermission_Read_Only) && - (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { - return true; - } - // The line must not be accessible - } - data_ptr = NULL; - return false; -} - -inline -bool CacheMemory::testCacheAccess(const Address& address, - CacheRequestType type, - DataBlock*& data_ptr) -{ - assert(address == line_address(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - if(loc != -1){ // Do we even have a tag match? - AbstractCacheEntry* entry = m_cache[cacheSet][loc]; - m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); - data_ptr = &(entry->getDataBlk()); - - return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent); - } - data_ptr = NULL; - return false; -} - -// tests to see if an address is present in the cache -inline -bool CacheMemory::isTagPresent(const Address& address) const -{ - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int location = findTagInSet(cacheSet, address); - - if (location == -1) { - // We didn't find the tag - DEBUG_EXPR(CACHE_COMP, LowPrio, address); - DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match"); - return false; - } - DEBUG_EXPR(CACHE_COMP, LowPrio, address); - DEBUG_MSG(CACHE_COMP, LowPrio, "found"); - return true; -} - -// Returns true if there is: -// a) a tag match on this address or there is -// b) an unused line in the same cache "way" -inline -bool CacheMemory::cacheAvail(const Address& address) const -{ - assert(address == line_address(address)); - - Index cacheSet = addressToCacheSet(address); - - for (int i=0; i < m_cache_assoc; i++) { - AbstractCacheEntry* entry = m_cache[cacheSet][i]; - if (entry != NULL) { - if (entry->m_Address == address || // Already in the cache - entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry - return true; - } - } else { - return true; - } - } - return false; -} - -inline -void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) -{ - assert(address == line_address(address)); - assert(!isTagPresent(address)); - assert(cacheAvail(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - - // Find the first open slot - Index cacheSet = addressToCacheSet(address); - for (int i=0; i < m_cache_assoc; i++) { - if (m_cache[cacheSet][i] == NULL || - m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) { - m_cache[cacheSet][i] = entry; // Init entry - m_cache[cacheSet][i]->m_Address = address; - m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; - m_locked[cacheSet][i] = -1; - m_tag_index[address] = i; - - m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime()); - - return; - } - } - ERROR_MSG("Allocate didn't find an available entry"); -} - -inline -void CacheMemory::deallocate(const Address& address) -{ - assert(address == line_address(address)); - assert(isTagPresent(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - Index cacheSet = addressToCacheSet(address); - int location = findTagInSet(cacheSet, address); - if (location != -1){ - delete m_cache[cacheSet][location]; - m_cache[cacheSet][location] = NULL; - m_locked[cacheSet][location] = -1; - m_tag_index.erase(address); - } -} - -// Returns with the physical address of the conflicting cache line -inline -Address CacheMemory::cacheProbe(const Address& address) const -{ - assert(address == line_address(address)); - assert(!cacheAvail(address)); - - Index cacheSet = addressToCacheSet(address); - return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address; -} - -// looks an address up in the cache -inline -AbstractCacheEntry& CacheMemory::lookup(const Address& address) -{ - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - return *m_cache[cacheSet][loc]; -} - -// looks an address up in the cache -inline -const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const -{ - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - return *m_cache[cacheSet][loc]; -} - -inline -AccessPermission CacheMemory::getPermission(const Address& address) const -{ - assert(address == line_address(address)); - return lookup(address).m_Permission; -} - -inline -void CacheMemory::changePermission(const Address& address, AccessPermission new_perm) -{ - assert(address == line_address(address)); - lookup(address).m_Permission = new_perm; - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - m_locked[cacheSet][loc] = -1; - assert(getPermission(address) == new_perm); -} - -// Sets the most recently used bit for a cache block -inline -void CacheMemory::setMRU(const Address& address) -{ - Index cacheSet; - - cacheSet = addressToCacheSet(address); - m_replacementPolicy_ptr->touch(cacheSet, - findTagInSet(cacheSet, address), - g_eventQueue_ptr->getTime()); -} - -inline -void CacheMemory::profileMiss(const CacheMsg & msg) -{ - m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(), - msg.getSize(), msg.getPrefetch()); -} - -inline -void CacheMemory::recordCacheContents(CacheRecorder& tr) const -{ - for (int i = 0; i < m_cache_num_sets; i++) { - for (int j = 0; j < m_cache_assoc; j++) { - AccessPermission perm = m_cache[i][j]->m_Permission; - CacheRequestType request_type = CacheRequestType_NULL; - if (perm == AccessPermission_Read_Only) { - if (m_is_instruction_only_cache) { - request_type = CacheRequestType_IFETCH; - } else { - request_type = CacheRequestType_LD; - } - } else if (perm == AccessPermission_Read_Write) { - request_type = CacheRequestType_ST; - } - - if (request_type != CacheRequestType_NULL) { - // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, - // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j)); - } - } - } -} - -inline -void CacheMemory::print(ostream& out) const -{ - out << "Cache dump: " << m_cache_name << endl; - for (int i = 0; i < m_cache_num_sets; i++) { - for (int j = 0; j < m_cache_assoc; j++) { - if (m_cache[i][j] != NULL) { - out << " Index: " << i - << " way: " << j - << " entry: " << *m_cache[i][j] << endl; - } else { - out << " Index: " << i - << " way: " << j - << " entry: NULL" << endl; - } - } - } -} - -inline -void CacheMemory::printData(ostream& out) const -{ - out << "printData() not supported" << endl; -} - -inline void CacheMemory::clearStats() const -{ - m_profiler_ptr->clearStats(); -} - -inline -void CacheMemory::printStats(ostream& out) const -{ - m_profiler_ptr->printStats(out); -} - -inline -void CacheMemory::getMemoryValue(const Address& addr, char* value, - unsigned int size_in_bytes ){ - AbstractCacheEntry& entry = lookup(line_address(addr)); - unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); - for(unsigned int i=0; i<size_in_bytes; ++i){ - value[i] = entry.getDataBlk().getByte(i + startByte); - } -} - -inline -void CacheMemory::setMemoryValue(const Address& addr, char* value, - unsigned int size_in_bytes ){ - AbstractCacheEntry& entry = lookup(line_address(addr)); - unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); - assert(size_in_bytes > 0); - for(unsigned int i=0; i<size_in_bytes; ++i){ - entry.getDataBlk().setByte(i + startByte, value[i]); - } - - // entry = lookup(line_address(addr)); -} - -inline -void -CacheMemory::setLocked(const Address& address, int context) -{ - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - m_locked[cacheSet][loc] = context; -} - -inline -void -CacheMemory::clearLocked(const Address& address) -{ - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - m_locked[cacheSet][loc] = -1; -} - -inline -bool -CacheMemory::isLocked(const Address& address, int context) -{ - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - return m_locked[cacheSet][loc] == context; -} +}; #endif //CACHEMEMORY_H diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc index 46ebdbab4..9b2a3873c 100644 --- a/src/mem/ruby/system/DirectoryMemory.cc +++ b/src/mem/ruby/system/DirectoryMemory.cc @@ -84,11 +84,14 @@ void DirectoryMemory::init(const vector<string> & argv) DirectoryMemory::~DirectoryMemory() { // free up all the directory entries - for (int i=0;i<m_num_entries;i++) - if (m_entries[i] != NULL) - delete m_entries; - if (m_entries != NULL) + for (uint64 i=0;i<m_num_entries;i++) { + if (m_entries[i] != NULL) { + delete m_entries[i]; + } + } + if (m_entries != NULL) { delete [] m_entries; + } } void DirectoryMemory::printConfig(ostream& out) const diff --git a/src/mem/ruby/system/PersistentTable.cc b/src/mem/ruby/system/PersistentTable.cc new file mode 100644 index 000000000..58b67ea60 --- /dev/null +++ b/src/mem/ruby/system/PersistentTable.cc @@ -0,0 +1,204 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mem/ruby/system/PersistentTable.hh" +#include "mem/gems_common/util.hh" + +// randomize so that handoffs are not locality-aware +// int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}; +// int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + + +PersistentTable::PersistentTable() +{ + m_map_ptr = new Map<Address, PersistentTableEntry>; +} + +PersistentTable::~PersistentTable() +{ + delete m_map_ptr; + m_map_ptr = NULL; +} + +void PersistentTable::persistentRequestLock(const Address& address, + MachineID locker, + AccessType type) +{ + + // if (locker == m_chip_ptr->getID() ) + // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker + // << " requesting lock for " << address << endl; + + // MachineID locker = (MachineID) persistent_randomize[llocker]; + + assert(address == line_address(address)); + if (!m_map_ptr->exist(address)) { + // Allocate if not present + PersistentTableEntry entry; + entry.m_starving.add(locker); + if (type == AccessType_Write) { + entry.m_request_to_write.add(locker); + } + m_map_ptr->add(address, entry); + } else { + PersistentTableEntry& entry = m_map_ptr->lookup(address); + + // + // Make sure we're not already in the locked set + // + assert(!(entry.m_starving.isElement(locker))); + + entry.m_starving.add(locker); + if (type == AccessType_Write) { + entry.m_request_to_write.add(locker); + } + assert(entry.m_marked.isSubset(entry.m_starving)); + } +} + +void PersistentTable::persistentRequestUnlock(const Address& address, + MachineID unlocker) +{ + // if (unlocker == m_chip_ptr->getID() ) + // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker + // << " requesting unlock for " << address << endl; + + // MachineID unlocker = (MachineID) persistent_randomize[uunlocker]; + + assert(address == line_address(address)); + assert(m_map_ptr->exist(address)); + PersistentTableEntry& entry = m_map_ptr->lookup(address); + + // + // Make sure we're in the locked set + // + assert(entry.m_starving.isElement(unlocker)); + assert(entry.m_marked.isSubset(entry.m_starving)); + entry.m_starving.remove(unlocker); + entry.m_marked.remove(unlocker); + entry.m_request_to_write.remove(unlocker); + assert(entry.m_marked.isSubset(entry.m_starving)); + + // Deallocate if empty + if (entry.m_starving.isEmpty()) { + assert(entry.m_marked.isEmpty()); + m_map_ptr->erase(address); + } +} + +bool PersistentTable::okToIssueStarving(const Address& address, + MachineID machId) const +{ + assert(address == line_address(address)); + if (!m_map_ptr->exist(address)) { + // + // No entry present + // + return true; + } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) { + // + // We can't issue another lockdown until are previous unlock has occurred + // + return false; + } else { + return (m_map_ptr->lookup(address).m_marked.isEmpty()); + } +} + +MachineID PersistentTable::findSmallest(const Address& address) const +{ + assert(address == line_address(address)); + assert(m_map_ptr->exist(address)); + const PersistentTableEntry& entry = m_map_ptr->lookup(address); + return entry.m_starving.smallestElement(); +} + +AccessType PersistentTable::typeOfSmallest(const Address& address) const +{ + assert(address == line_address(address)); + assert(m_map_ptr->exist(address)); + const PersistentTableEntry& entry = m_map_ptr->lookup(address); + if (entry.m_request_to_write.isElement(entry.m_starving.smallestElement())) { + return AccessType_Write; + } else { + return AccessType_Read; + } +} + +void PersistentTable::markEntries(const Address& address) +{ + assert(address == line_address(address)); + if (m_map_ptr->exist(address)) { + PersistentTableEntry& entry = m_map_ptr->lookup(address); + + // + // None should be marked + // + assert(entry.m_marked.isEmpty()); + + // + // Mark all the nodes currently in the table + // + entry.m_marked = entry.m_starving; + } +} + +bool PersistentTable::isLocked(const Address& address) const +{ + assert(address == line_address(address)); + // If an entry is present, it must be locked + return (m_map_ptr->exist(address)); +} + +int PersistentTable::countStarvingForAddress(const Address& address) const +{ + if (m_map_ptr->exist(address)) { + PersistentTableEntry& entry = m_map_ptr->lookup(address); + return (entry.m_starving.count()); + } + else { + return 0; + } +} + +int PersistentTable::countReadStarvingForAddress(const Address& address) const +{ + if (m_map_ptr->exist(address)) { + PersistentTableEntry& entry = m_map_ptr->lookup(address); + return (entry.m_starving.count() - entry.m_request_to_write.count()); + } + else { + return 0; + } +} + +void PersistentTable::print(ostream& out) const +{ +} + diff --git a/src/mem/slicc/ast/InfixOperatorExprAST.hh b/src/mem/ruby/system/PersistentTable.hh index f97ab8805..8cbb48817 100644 --- a/src/mem/slicc/ast/InfixOperatorExprAST.hh +++ b/src/mem/ruby/system/PersistentTable.hh @@ -27,59 +27,76 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * InfixOperatorExprAST.hh - * - * Description: - * - * $Id: InfixOperatorExprAST.hh,v 3.1 2001/12/12 01:00:19 milo Exp $ - * - */ +#ifndef PersistentTable_H +#define PersistentTable_H -#ifndef INFIXOPERATOREXPRAST_H -#define INFIXOPERATOREXPRAST_H +#include "mem/ruby/common/Global.hh" +#include "mem/gems_common/Map.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/system/MachineID.hh" +#include "mem/protocol/AccessType.hh" +#include "mem/ruby/common/NetDest.hh" -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" +class PersistentTableEntry { +public: + void print(ostream& out) const {} + NetDest m_starving; + NetDest m_marked; + NetDest m_request_to_write; +}; -class InfixOperatorExprAST : public ExprAST { +class PersistentTable { public: // Constructors - InfixOperatorExprAST(ExprAST* left_ptr, string* op_ptr, ExprAST* right_ptr); + PersistentTable(); // Destructor - ~InfixOperatorExprAST(); - + ~PersistentTable(); + // Public Methods - Type* generate(string& code) const; + void persistentRequestLock(const Address& address, MachineID locker, AccessType type); + void persistentRequestUnlock(const Address& address, MachineID unlocker); + bool okToIssueStarving(const Address& address, MachineID machID) const; + MachineID findSmallest(const Address& address) const; + AccessType typeOfSmallest(const Address& address) const; + void markEntries(const Address& address); + bool isLocked(const Address& addr) const; + int countStarvingForAddress(const Address& addr) const; + int countReadStarvingForAddress(const Address& addr) const; + + static void printConfig(ostream& out) {} + void print(ostream& out) const; private: // Private Methods // Private copy constructor and assignment operator - InfixOperatorExprAST(const InfixOperatorExprAST& obj); - InfixOperatorExprAST& operator=(const InfixOperatorExprAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_left_ptr; - string* m_op_ptr; - ExprAST* m_right_ptr; + PersistentTable(const PersistentTable& obj); + PersistentTable& operator=(const PersistentTable& obj); + // Data Members (m_prefix) + Map<Address, PersistentTableEntry>* m_map_ptr; }; -// Output operator declaration -ostream& operator<<(ostream& out, const InfixOperatorExprAST& obj); - // ******************* Definitions ******************* // Output operator definition extern inline -ostream& operator<<(ostream& out, const InfixOperatorExprAST& obj) +ostream& operator<<(ostream& out, const PersistentTable& obj) +{ + obj.print(out); + out << flush; + return out; +} + +// Output operator definition +extern inline +ostream& operator<<(ostream& out, const PersistentTableEntry& obj) { obj.print(out); out << flush; return out; } -#endif //INFIXOPERATOREXPRAST_H +#endif //PersistentTable_H diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript index 1d8b1e2df..4ca1af114 100644 --- a/src/mem/ruby/system/SConscript +++ b/src/mem/ruby/system/SConscript @@ -35,8 +35,10 @@ if not env['RUBY']: Source('DMASequencer.cc') Source('DirectoryMemory.cc') +Source('CacheMemory.cc') Source('MemoryControl.cc') Source('MemoryNode.cc') +Source('PersistentTable.cc') Source('RubyPort.cc') Source('Sequencer.cc', Werror=False) Source('System.cc') diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh index 231df01bb..ce53dd8d7 100644 --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -63,6 +63,8 @@ struct SequencerRequest { {} }; +std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj); + class Sequencer : public Consumer, public RubyPort { public: // Constructors diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh index 38ef09177..1d36de878 100644 --- a/src/mem/ruby/system/System.hh +++ b/src/mem/ruby/system/System.hh @@ -107,7 +107,10 @@ public: if (m_ports.count(name) != 1){ cerr << "Port " << name << " has " << m_ports.count(name) << " instances" << endl; } - assert(m_ports.count(name) == 1); m_ports[name]->registerHitCallback(hit_callback); return m_ports[name]; } + assert(m_ports.count(name) == 1); + m_ports[name]->registerHitCallback(hit_callback); + return m_ports[name]; + } static Network* getNetwork() { assert(m_network_ptr != NULL); return m_network_ptr; } static Topology* getTopology(const string & name) { assert(m_topologies.count(name) == 1); return m_topologies[name]; } static CacheMemory* getCache(const string & name) { assert(m_caches.count(name) == 1); return m_caches[name]; } diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index 4d9f8051f..74a6e390e 100644 --- a/src/mem/rubymem.cc +++ b/src/mem/rubymem.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,6 +27,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Daniel Sanchez + * Brad Beckmann */ #include <iostream> @@ -35,6 +37,7 @@ #include "base/output.hh" #include "base/str.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "mem/ruby/common/Debug.hh" #include "mem/ruby/libruby.hh" #include "mem/ruby/system/RubyPort.hh" @@ -55,13 +58,23 @@ RubyMemory::RubyMemory(const Params *p) ruby_clock = p->clock; ruby_phase = p->phase; + ports_per_cpu = p->ports_per_core; + + DPRINTF(Ruby, "creating Ruby Memory from file %s\n", + p->config_file.c_str()); + ifstream config(p->config_file.c_str()); + if (config.good() == false) { + fatal("Did not successfully open %s.\n", p->config_file.c_str()); + } + vector<RubyObjConf> sys_conf; while (!config.eof()) { - char buffer[4096]; + char buffer[65536]; config.getline(buffer, sizeof(buffer)); string line = buffer; + DPRINTF(Ruby, "%s %d\n", line, line.empty()); if (line.empty()) continue; vector<string> tokens; @@ -80,11 +93,27 @@ RubyMemory::RubyMemory(const Params *p) RubySystem::create(sys_conf); + // + // Create the necessary ruby_ports to connect to the sequencers. + // This code should be fixed when the configuration systems are unified + // and the ruby configuration text files no longer exist. Also, + // it would be great to remove the single ruby_hit_callback func with + // separate pointers to particular ports to rubymem. However, functional + // access currently prevent the improvement. + // for (int i = 0; i < params()->num_cpus; i++) { RubyPort *p = RubySystem::getPort(csprintf("Sequencer_%d", i), ruby_hit_callback); ruby_ports.push_back(p); } + + for (int i = 0; i < params()->num_dmas; i++) { + RubyPort *p = RubySystem::getPort(csprintf("DMASequencer_%d", i), + ruby_hit_callback); + ruby_dma_ports.push_back(p); + } + + pio_port = NULL; } void @@ -105,7 +134,6 @@ RubyMemory::init() //g_debug_ptr->setDebugTime(1); //g_debug_ptr->setDebugOutputFile("ruby.debug"); - g_system_ptr->clearStats(); if (ports.size() == 0) { @@ -117,9 +145,18 @@ RubyMemory::init() (*pi)->sendStatusChange(Port::RangeChange); } + for (PortIterator pi = dma_ports.begin(); pi != dma_ports.end(); ++pi) { + if (*pi) + (*pi)->sendStatusChange(Port::RangeChange); + } + + if (pio_port != NULL) { + pio_port->sendStatusChange(Port::RangeChange); + } + //Print stats at exit - RubyExitCallback* rc = new RubyExitCallback(this); - registerExitCallback(rc); + rubyExitCB = new RubyExitCallback(this); + registerExitCallback(rubyExitCB); //Sched RubyEvent, automatically reschedules to advance ruby cycles rubyTickEvent = new RubyEvent(this); @@ -137,37 +174,57 @@ RubyMemory::tick() RubyMemory::~RubyMemory() { -} - -void -RubyMemory::hitCallback(PacketPtr pkt, Port *port) -{ - DPRINTF(MemoryAccess, "Hit callback\n"); - - bool needsResponse = pkt->needsResponse(); - doAtomicAccess(pkt); - - // turn packet around to go back to requester if response expected - if (needsResponse) { - // recvAtomic() should already have turned packet into - // atomic response - assert(pkt->isResponse()); - DPRINTF(MemoryAccess, "Sending packet back over port\n"); - port->sendTiming(pkt); - } else { - delete pkt; - } - DPRINTF(MemoryAccess, "Hit callback done!\n"); + delete g_system_ptr; } Port * RubyMemory::getPort(const std::string &if_name, int idx) { + DPRINTF(Ruby, "getting port %d %s\n", idx, if_name); + DPRINTF(Ruby, + "number of ruby ports %d and dma ports %d\n", + ruby_ports.size(), + ruby_dma_ports.size()); + + // + // By default, getPort will be passed an idx of -1. Of course this is an + // invalid ruby port index and must be a modified + // + if (idx == -1) { + idx = 0; + } + // Accept request for "functional" port for backwards compatibility // with places where this function is called from C++. I'd prefer // to move all these into Python someday. if (if_name == "functional") { - return new Port(csprintf("%s-functional", name()), this); + assert(idx < ruby_ports.size()); + return new Port(csprintf("%s-functional", name()), + this, + ruby_ports[idx]); + } + + // + // if dma port request, allocate the appropriate prot + // + if (if_name == "dma_port") { + assert(idx < ruby_dma_ports.size()); + RubyMemory::Port* dma_port = + new Port(csprintf("%s-dma_port%d", name(), idx), + this, + ruby_dma_ports[idx]); + dma_ports.push_back(dma_port); + return dma_port; + } + + // + // if pio port, ensure that there is only one + // + if (if_name == "pio_port") { + assert(pio_port == NULL); + pio_port = + new RubyMemory::Port("ruby_pio_port", this, NULL); + return pio_port; } if (if_name != "port") { @@ -182,30 +239,68 @@ RubyMemory::getPort(const std::string &if_name, int idx) panic("RubyMemory::getPort: port %d already assigned", idx); } - Port *port = new Port(csprintf("%s-port%d", name(), idx), this); + // + // Currently this code assumes that each cpu has both a + // icache and dcache port and therefore divides by ports per cpu. This will + // be fixed once we unify the configuration systems and Ruby sequencers + // directly support M5 ports. + // + assert(idx/ports_per_cpu < ruby_ports.size()); + Port *port = new Port(csprintf("%s-port%d", name(), idx), + this, + ruby_ports[idx/ports_per_cpu]); ports[idx] = port; return port; } -RubyMemory::Port::Port(const std::string &_name, RubyMemory *_memory) +RubyMemory::Port::Port(const std::string &_name, + RubyMemory *_memory, + RubyPort *_port) : PhysicalMemory::MemoryPort::MemoryPort(_name, _memory) { + DPRINTF(Ruby, "creating port to ruby memory %s\n", _name); ruby_mem = _memory; + ruby_port = _port; } bool RubyMemory::Port::recvTiming(PacketPtr pkt) { - DPRINTF(MemoryAccess, "Timing access caught\n"); + DPRINTF(MemoryAccess, + "Timing access caught for address %#x\n", + pkt->getAddr()); //dsm: based on SimpleTimingPort::recvTiming(pkt); - // If the device is only a slave, it should only be sending - // responses, which should never get nacked. There used to be - // code to hanldle nacks here, but I'm pretty sure it didn't work - // correctly with the drain code, so that would need to be fixed - // if we ever added it back. + // + // In FS mode, ruby memory will receive pio responses from devices and + // it must forward these responses back to the particular CPU. + // + if (pkt->isResponse() != false && isPioAddress(pkt->getAddr()) != false) { + DPRINTF(MemoryAccess, + "Pio Response callback %#x\n", + pkt->getAddr()); + RubyMemory::SenderState *senderState = + safe_cast<RubyMemory::SenderState *>(pkt->senderState); + RubyMemory::Port *port = senderState->port; + + // pop the sender state from the packet + pkt->senderState = senderState->saved; + delete senderState; + + port->sendTiming(pkt); + + return true; + } + + // + // After checking for pio responses, the remainder of packets + // received by ruby should only be M5 requests, which should never + // get nacked. There used to be code to hanldle nacks here, but + // I'm pretty sure it didn't work correctly with the drain code, + // so that would need to be fixed if we ever added it back. + // assert(pkt->isRequest()); if (pkt->memInhibitAsserted()) { @@ -219,6 +314,18 @@ RubyMemory::Port::recvTiming(PacketPtr pkt) // Save the port in the sender state object pkt->senderState = new SenderState(this, pkt->senderState); + // + // Check for pio requests and directly send them to the dedicated + // pio_port. + // + if (isPioAddress(pkt->getAddr()) != false) { + return ruby_mem->pio_port->sendTiming(pkt); + } + + // + // For DMA and CPU requests, translate them to ruby requests before + // sending them to our assigned ruby port. + // RubyRequestType type = RubyRequestType_NULL; Addr pc = 0; if (pkt->isRead()) { @@ -239,7 +346,6 @@ RubyMemory::Port::recvTiming(PacketPtr pkt) RubyAccessMode_Supervisor); // Submit the ruby request - RubyPort *ruby_port = ruby_mem->ruby_ports[pkt->req->contextId()]; int64_t req_id = ruby_port->makeRequest(ruby_request); if (req_id == -1) { RubyMemory::SenderState *senderState = @@ -260,6 +366,12 @@ RubyMemory::Port::recvTiming(PacketPtr pkt) void ruby_hit_callback(int64_t req_id) { + // + // Note: This single fuction can be called by cpu and dma ports, + // as well as the functional port. The functional port prevents + // us from replacing this single function with separate port + // functions. + // typedef map<int64_t, PacketPtr> map_t; map_t &prm = RubyMemory::pending_requests; @@ -278,13 +390,58 @@ ruby_hit_callback(int64_t req_id) pkt->senderState = senderState->saved; delete senderState; - port->ruby_mem->hitCallback(pkt, port); + port->hitCallback(pkt); } void +RubyMemory::Port::hitCallback(PacketPtr pkt) +{ + + bool needsResponse = pkt->needsResponse(); + + DPRINTF(MemoryAccess, "Hit callback needs response %d\n", + needsResponse); + + ruby_mem->doAtomicAccess(pkt); + + // turn packet around to go back to requester if response expected + if (needsResponse) { + // recvAtomic() should already have turned packet into + // atomic response + assert(pkt->isResponse()); + DPRINTF(MemoryAccess, "Sending packet back over port\n"); + sendTiming(pkt); + } else { + delete pkt; + } + DPRINTF(MemoryAccess, "Hit callback done!\n"); +} + +bool RubyMemory::Port::sendTiming(PacketPtr pkt) { schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0 + return true; +} + +bool +RubyMemory::Port::isPioAddress(Addr addr) +{ + AddrRangeList pioAddrList; + bool snoop = false; + if (ruby_mem->pio_port == NULL) { + return false; + } + + ruby_mem->pio_port->getPeerAddressRanges(pioAddrList, snoop); + for(AddrRangeIter iter = pioAddrList.begin(); iter != pioAddrList.end(); iter++) { + if (addr >= iter->start && addr <= iter->end) { + DPRINTF(MemoryAccess, "Pio request found in %#llx - %#llx range\n", + iter->start, iter->end); + return true; + } + } + return false; } void RubyMemory::printConfigStats() @@ -311,6 +468,17 @@ void RubyMemory::printConfig(std::ostream & out) const { //g_system_ptr->printConfig(out); } +void RubyMemory::serialize(ostream &os) +{ + PhysicalMemory::serialize(os); +} + +void RubyMemory::unserialize(Checkpoint *cp, const string §ion) +{ + DPRINTF(Config, "Ruby memory being restored\n"); + reschedule(rubyTickEvent, curTick + ruby_clock + ruby_phase); + PhysicalMemory::unserialize(cp, section); +} //Python-interface code RubyMemory * diff --git a/src/mem/rubymem.hh b/src/mem/rubymem.hh index e33418a42..2672dcb77 100644 --- a/src/mem/rubymem.hh +++ b/src/mem/rubymem.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,23 +40,34 @@ #include "mem/physical.hh" #include "mem/ruby/system/RubyPort.hh" #include "params/RubyMemory.hh" +#include "mem/port.hh" + +class RubyExitCallback; class RubyMemory : public PhysicalMemory { public: std::vector<RubyPort *> ruby_ports; + std::vector<RubyPort *> ruby_dma_ports; class Port : public MemoryPort { friend void ruby_hit_callback(int64_t req_id); RubyMemory *ruby_mem; + RubyPort *ruby_port; public: - Port(const std::string &_name, RubyMemory *_memory); - void sendTiming(PacketPtr pkt); + Port(const std::string &_name, + RubyMemory *_memory, + RubyPort *_port); + bool sendTiming(PacketPtr pkt); + void hitCallback(PacketPtr pkt); protected: virtual bool recvTiming(PacketPtr pkt); + + private: + bool isPioAddress(Addr addr); }; class RubyEvent : public Event @@ -108,8 +120,6 @@ class RubyMemory : public PhysicalMemory //options change & M5 determines the //stats file to use - void hitCallback(PacketPtr pkt, Port *port); - void printStats(std::ostream & out) const; void clearStats(); void printConfig(std::ostream & out) const; @@ -119,9 +129,19 @@ class RubyMemory : public PhysicalMemory private: Tick ruby_clock; Tick ruby_phase; + RubyExitCallback* rubyExitCB; + int ports_per_cpu; public: static std::map<int64_t, PacketPtr> pending_requests; + RubyMemory::Port* pio_port; + + protected: + std::vector<MemoryPort*> dma_ports; + + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; void ruby_hit_callback(int64_t); diff --git a/src/mem/slicc/SConscript b/src/mem/slicc/SConscript deleted file mode 100644 index e26ceb979..000000000 --- a/src/mem/slicc/SConscript +++ /dev/null @@ -1,129 +0,0 @@ -# -*- mode:python -*- - -# Copyright (c) 2009 The Hewlett-Packard Development Company -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Nathan Binkert - -import os -import re -import string -import sys - -from os.path import basename, dirname, exists, expanduser, isdir, isfile -from os.path import join as joinpath - -import SCons - -Import('*') - -if not env['RUBY']: - Return() - -common_dir = Dir('../gems_common') - -# -# Build SLICC -# -slicc_env = env.Clone() -slicc_env['CPPDEFINES'] = '' -slicc_env['CPPPATH'] = Dir('../..') -slicc_env.Append(CCFLAGS=['-g', '-O0']) -slicc_env.Append(CPPDEFINES=['DEBUG', 'TRACING_ON=1']) -slicc_env['LIBS'] = '' -slicc_env['LIBPATH'] = '' -all_slicc_sources = [] -def SliccSource(filename): - if filename.endswith('.ll') or filename.endswith('.yy'): - slicc_env.CXXFile(filename) - filename = filename[:-2] + "cc" - x = slicc_env.StaticObject(filename) - all_slicc_sources.append(x) - return x - -# BE CAREFUL WITH THE ORDER OF FILENAMES HERE. SLICC IS VERY FRAGILE -# BECAUSE IT VIOLATES ESTABLISHED RULES ABOUT HOW YOU'RE ALLOWED TO -# CREATE STATIC OBJECTS. (SLICC HAS DEPENDENCIES DURING STATIC OBJECT -# CONSTRUCTION ACROSS FILES. THAT'S A NO-NO.) WITH THIS FILE ORDER, -# WE GET LUCKY AND OBJECTS GET CONSTRUCTED IN THE RIGHT ORDER. -SliccSource('parser/parser.yy') -SliccSource('parser/lexer.ll') -SliccSource('main.cc') -SliccSource('symbols/Func.cc') -SliccSource('symbols/StateMachine.cc') -SliccSource('symbols/Symbol.cc') -SliccSource('symbols/SymbolTable.cc') -SliccSource('symbols/Transition.cc') -SliccSource('symbols/Type.cc') -SliccSource('symbols/Var.cc') -SliccSource('generator/fileio.cc') -SliccSource('generator/html_gen.cc') -SliccSource('generator/mif_gen.cc') -SliccSource('ast/AST.cc') -SliccSource('ast/ActionDeclAST.cc') -SliccSource('ast/AssignStatementAST.cc') -SliccSource('ast/CheckAllocateStatementAST.cc') -SliccSource('ast/CheckStopSlotsStatementAST.cc') -SliccSource('ast/ChipComponentAccessAST.cc') -SliccSource('ast/CopyHeadStatementAST.cc') -SliccSource('ast/DeclAST.cc') -SliccSource('ast/DeclListAST.cc') -SliccSource('ast/EnqueueStatementAST.cc') -SliccSource('ast/EnumDeclAST.cc') -SliccSource('ast/EnumExprAST.cc') -SliccSource('ast/ExprAST.cc') -SliccSource('ast/ExprStatementAST.cc') -SliccSource('ast/FormalParamAST.cc') -SliccSource('ast/FuncCallExprAST.cc') -SliccSource('ast/FuncDeclAST.cc') -SliccSource('ast/IfStatementAST.cc') -SliccSource('ast/InPortDeclAST.cc') -SliccSource('ast/InfixOperatorExprAST.cc') -SliccSource('ast/LiteralExprAST.cc') -SliccSource('ast/Location.cc') -SliccSource('ast/MachineAST.cc') -SliccSource('ast/MemberExprAST.cc') -SliccSource('ast/MethodCallExprAST.cc') -SliccSource('ast/NewExprAST.cc') -SliccSource('ast/ObjDeclAST.cc') -SliccSource('ast/OutPortDeclAST.cc') -SliccSource('ast/PairAST.cc') -SliccSource('ast/PairListAST.cc') -SliccSource('ast/PeekStatementAST.cc') -SliccSource('ast/ReturnStatementAST.cc') -SliccSource('ast/StatementAST.cc') -SliccSource('ast/StatementListAST.cc') -SliccSource('ast/TransitionDeclAST.cc') -SliccSource('ast/TypeAST.cc') -SliccSource('ast/TypeDeclAST.cc') -SliccSource('ast/TypeFieldAST.cc') -SliccSource('ast/TypeFieldEnumAST.cc') -SliccSource('ast/TypeFieldMemberAST.cc') -SliccSource('ast/TypeFieldMethodAST.cc') -SliccSource('ast/VarExprAST.cc') - -slicc_bin = File('slicc') -slicc_env.Program(slicc_bin, all_slicc_sources + [ common_dir.File('util.o') ]) diff --git a/src/mem/slicc/__init__.py b/src/mem/slicc/__init__.py new file mode 100644 index 000000000..8ce04e77d --- /dev/null +++ b/src/mem/slicc/__init__.py @@ -0,0 +1,25 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/mem/slicc/ast/AST.hh b/src/mem/slicc/ast/AST.hh deleted file mode 100644 index 33c9b84ed..000000000 --- a/src/mem/slicc/ast/AST.hh +++ /dev/null @@ -1,94 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * AST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef AST_H -#define AST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Vector.hh" -#include "mem/gems_common/Map.hh" -#include "mem/slicc/ast/Location.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -class AST { -public: - // Constructors - AST(Map<string, string> pairs) { m_pairs = pairs; }; - AST() {}; - - // Destructor - virtual ~AST() {}; - - // Public Methods - virtual void print(ostream& out) const = 0; - void error(string err_msg) const { m_location.error(err_msg); }; - string embedError(string err_msg) const { return m_location.embedError(err_msg); }; - void warning(string err_msg) const { m_location.warning(err_msg); }; - - const Location& getLocation() const { return m_location; }; - - const Map<string, string>& getPairs() const { return m_pairs; }; - Map<string, string>& getPairs() { return m_pairs; }; - -private: - // Private Methods - - // Private copy constructor and assignment operator - // AST(const AST& obj); - // AST& operator=(const AST& obj); - - // Data Members (m_ prefix) - Location m_location; - Map<string, string> m_pairs; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const AST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const AST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //AST_H diff --git a/src/mem/slicc/ast/AST.py b/src/mem/slicc/ast/AST.py new file mode 100644 index 000000000..5b1b124cd --- /dev/null +++ b/src/mem/slicc/ast/AST.py @@ -0,0 +1,63 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.util import PairContainer, Location + +class AST(PairContainer): + def __init__(self, slicc, pairs=None): + self.slicc = slicc + self.location = Location(slicc.current_file, slicc.lexer.lineno) + self.pairs = {} + if pairs: + self.pairs.update(getattr(pairs, "pairs", pairs)) + + @property + def symtab(self): + return self.slicc.symtab + + @property + def state_machine(self): + return self.slicc.symtab.state_machine + + def warning(self, message, *args): + self.location.warning(message, *args) + + def error(self, message, *args): + self.location.error(message, *args) + + def embedError(self, message, *args): + if args: + message = message % args + code = code_formatter() + code(''' +cerr << "Runtime Error at ${{self.location}}, Ruby Time: " << g_eventQueue_ptr->getTime() << ": "<< $message << ", PID: " << getpid() << endl; +char c; cerr << "press return to continue." << endl; cin.get(c); abort(); +''') + + return code diff --git a/src/mem/slicc/ast/ASTs.hh b/src/mem/slicc/ast/ASTs.hh deleted file mode 100644 index 3363fbb09..000000000 --- a/src/mem/slicc/ast/ASTs.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#ifndef ASTs_H -#define ASTs_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/main.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/AST.hh" - -#include "mem/slicc/ast/MachineAST.hh" - -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/FormalParamAST.hh" - -#include "mem/slicc/ast/DeclListAST.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/ActionDeclAST.hh" -#include "mem/slicc/ast/InPortDeclAST.hh" -#include "mem/slicc/ast/OutPortDeclAST.hh" -#include "mem/slicc/ast/TransitionDeclAST.hh" -#include "mem/slicc/ast/EnumDeclAST.hh" -#include "mem/slicc/ast/TypeDeclAST.hh" -#include "mem/slicc/ast/ObjDeclAST.hh" -#include "mem/slicc/ast/FuncDeclAST.hh" - -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/TypeFieldMethodAST.hh" -#include "mem/slicc/ast/TypeFieldMemberAST.hh" -#include "mem/slicc/ast/TypeFieldEnumAST.hh" - -#include "mem/slicc/ast/PairAST.hh" -#include "mem/slicc/ast/PairListAST.hh" - -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/EnumExprAST.hh" -#include "mem/slicc/ast/LiteralExprAST.hh" -#include "mem/slicc/ast/MemberExprAST.hh" -#include "mem/slicc/ast/InfixOperatorExprAST.hh" -#include "mem/slicc/ast/FuncCallExprAST.hh" -#include "mem/slicc/ast/MethodCallExprAST.hh" -#include "mem/slicc/ast/NewExprAST.hh" - -#include "mem/slicc/ast/ChipComponentAccessAST.hh" - -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprStatementAST.hh" -#include "mem/slicc/ast/AssignStatementAST.hh" -#include "mem/slicc/ast/EnqueueStatementAST.hh" -#include "mem/slicc/ast/IfStatementAST.hh" -#include "mem/slicc/ast/PeekStatementAST.hh" -#include "mem/slicc/ast/CopyHeadStatementAST.hh" -#include "mem/slicc/ast/CheckAllocateStatementAST.hh" -#include "mem/slicc/ast/CheckStopSlotsStatementAST.hh" -#include "mem/slicc/ast/ReturnStatementAST.hh" - -#endif //ASTs_H diff --git a/src/mem/slicc/ast/ActionDeclAST.cc b/src/mem/slicc/ast/ActionDeclAST.cc deleted file mode 100644 index e46412ff7..000000000 --- a/src/mem/slicc/ast/ActionDeclAST.cc +++ /dev/null @@ -1,98 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ActionDeclAST.C - * - * Description: See ActionDeclAST.hh - * - * $Id$ - * - */ - - -#include "mem/slicc/ast/ActionDeclAST.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/slicc/ast/StatementListAST.hh" - -ActionDeclAST::ActionDeclAST(string* ident_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr) - : DeclAST(pairs_ptr) -{ - m_ident_ptr = ident_ptr; - m_statement_list_ptr = statement_list_ptr; -} - -ActionDeclAST::~ActionDeclAST() -{ - delete m_ident_ptr; - delete m_statement_list_ptr; -} - -void ActionDeclAST::generate() -{ - Map<Var*, string> resource_list; - if (m_statement_list_ptr != NULL) { - string code; - - // Add new local vars - g_sym_table.pushFrame(); - - Type* type_ptr = g_sym_table.getType("Address"); - - if (type_ptr == NULL) { - error("Type 'Address' not declared."); - } - - g_sym_table.newSym(new Var("address", getLocation(), type_ptr, "addr", getPairs())); - - // Don't allows returns in actions - m_statement_list_ptr->generate(code, NULL); - - getPairs().add("c_code", code); - - m_statement_list_ptr->findResources(resource_list); - - g_sym_table.popFrame(); - } - - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr == NULL) { - error("Action declaration not part of a machine."); - } else { - machine_ptr->addAction(new Action(*m_ident_ptr, resource_list, getLocation(), getPairs())); - } - -} - -void ActionDeclAST::print(ostream& out) const -{ - out << "[ActionDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/ActionDeclAST.hh b/src/mem/slicc/ast/ActionDeclAST.hh deleted file mode 100644 index 4970ee254..000000000 --- a/src/mem/slicc/ast/ActionDeclAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ActionDeclAST.hh - * - * Description: - * - * $Id: ActionDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef ActionDeclAST_H -#define ActionDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" - -class StatementListAST; - -class ActionDeclAST : public DeclAST { -public: - // Constructors - ActionDeclAST(string* ident_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr); - - // Destructor - ~ActionDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ActionDeclAST(const ActionDeclAST& obj); - ActionDeclAST& operator=(const ActionDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - StatementListAST* m_statement_list_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ActionDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ActionDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ActionDeclAST_H diff --git a/src/mem/slicc/ast/ActionDeclAST.py b/src/mem/slicc/ast/ActionDeclAST.py new file mode 100644 index 000000000..18bf443b9 --- /dev/null +++ b/src/mem/slicc/ast/ActionDeclAST.py @@ -0,0 +1,72 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Action, Type, Var + +class ActionDeclAST(DeclAST): + def __init__(self, slicc, ident, pairs, statement_list): + super(ActionDeclAST, self).__init__(slicc, pairs) + self.ident = ident + self.statement_list = statement_list + + def __repr__(self): + return "[ActionDecl: %r]" % (self.ident) + + def generate(self): + resources = {} + if self.statement_list: + # Add new local vars + self.symtab.pushFrame() + + addr_type = self.symtab.find("Address", Type) + + if addr_type is None: + self.error("Type 'Address' not declared.") + + var = Var(self.symtab, "address", self.location, addr_type, + "addr", self.pairs) + self.symtab.newSymbol(var) + + # Do not allows returns in actions + code = code_formatter() + self.statement_list.generate(code, None) + self.pairs["c_code"] = str(code) + + self.statement_list.findResources(resources) + + self.symtab.popFrame() + + machine = self.symtab.state_machine + if machine is None: + self.error("Action declaration not part of a machine.") + + action = Action(self.symtab, self.ident, resources, self.location, + self.pairs) + machine.addAction(action) diff --git a/src/mem/slicc/ast/AssignStatementAST.cc b/src/mem/slicc/ast/AssignStatementAST.cc deleted file mode 100644 index 8cf42aa63..000000000 --- a/src/mem/slicc/ast/AssignStatementAST.cc +++ /dev/null @@ -1,76 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * AssignStatementAST.C - * - * Description: See AssignStatementAST.hh - * - * $Id: AssignStatementAST.C,v 3.2 2003/08/01 18:38:19 beckmann Exp $ - * - */ - -#include "mem/slicc/ast/AssignStatementAST.hh" - -AssignStatementAST::AssignStatementAST(ExprAST* lvalue_ptr, ExprAST* rvalue_ptr) - : StatementAST() -{ - m_lvalue_ptr = lvalue_ptr; - m_rvalue_ptr = rvalue_ptr; -} - -AssignStatementAST::~AssignStatementAST() -{ - delete m_lvalue_ptr; - delete m_rvalue_ptr; -} - -void AssignStatementAST::generate(string& code, Type* return_type_ptr) const -{ - code += indent_str(); - Type* lvalue_type_ptr = m_lvalue_ptr->generate(code); - code += " = "; - Type* rvalue_type_ptr = m_rvalue_ptr->generate(code); - code += ";\n"; - - if (lvalue_type_ptr != rvalue_type_ptr) { - // FIXME - beckmann - // the following if statement is a hack to allow NetDest objects to be assigned to Sets - // this allows for the previous NetworkMessage Destiantion 'Set class' to migrate to the - // new NetworkMessage Destiantion 'NetDest class' - if (lvalue_type_ptr->toString() != "NetDest" && rvalue_type_ptr->toString() != "Set") { - error("Assignment type mismatch '" + lvalue_type_ptr->toString() + "' and '" + rvalue_type_ptr->toString() + "'"); - } - } -} - -void AssignStatementAST::print(ostream& out) const -{ - out << "[AssignStatementAST: " << *m_lvalue_ptr << " := " << *m_rvalue_ptr << "]"; -} diff --git a/src/mem/slicc/ast/AssignStatementAST.hh b/src/mem/slicc/ast/AssignStatementAST.hh deleted file mode 100644 index 2c19da831..000000000 --- a/src/mem/slicc/ast/AssignStatementAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * AssignStatementAST.hh - * - * Description: - * - * $Id: AssignStatementAST.hh,v 3.2 2001/12/12 01:00:09 milo Exp $ - * - */ - -#ifndef ASSIGNSTATEMENTAST_H -#define ASSIGNSTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - - - -class AssignStatementAST : public StatementAST { -public: - // Constructors - AssignStatementAST(ExprAST* lvalue_ptr, ExprAST* rvalue_ptr); - - // Destructor - ~AssignStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - AssignStatementAST(const AssignStatementAST& obj); - AssignStatementAST& operator=(const AssignStatementAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_lvalue_ptr; - ExprAST* m_rvalue_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const AssignStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const AssignStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ASSIGNSTATEMENTAST_H diff --git a/src/mem/slicc/ast/AssignStatementAST.py b/src/mem/slicc/ast/AssignStatementAST.py new file mode 100644 index 000000000..f8e77b03b --- /dev/null +++ b/src/mem/slicc/ast/AssignStatementAST.py @@ -0,0 +1,59 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.StatementAST import StatementAST + +class AssignStatementAST(StatementAST): + def __init__(self, slicc, lvalue, rvalue): + super(AssignStatementAST, self).__init__(slicc) + self.lvalue = lvalue + self.rvalue = rvalue + + def __repr__(self): + return "[AssignStatementAST: %r := %r]" % (self.lvalue, self.rvalue) + + def generate(self, code, return_type): + lcode = code_formatter() + rcode = code_formatter() + + ltype = self.lvalue.generate(lcode) + rtype = self.rvalue.generate(rcode) + + code("$lcode = $rcode;") + + if ltype != rtype: + # FIXME - beckmann + # the following if statement is a hack to allow NetDest + # objects to be assigned to Sets this allows for the + # previous NetworkMessage Destiantion 'Set class' to + # migrate to the new NetworkMessage Destiantion 'NetDest + # class' + if str(ltype) != "NetDest" and str(rtype) != "Set": + self.error("Assignment type mismatch '%s' and '%s'", + ltype, rtype) diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.cc b/src/mem/slicc/ast/CheckAllocateStatementAST.cc deleted file mode 100644 index 1f498efe2..000000000 --- a/src/mem/slicc/ast/CheckAllocateStatementAST.cc +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/ast/CheckAllocateStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/gems_common/util.hh" - -CheckAllocateStatementAST::CheckAllocateStatementAST(VarExprAST* variable) - : StatementAST() -{ - m_variable = variable; -} - -CheckAllocateStatementAST::~CheckAllocateStatementAST() -{ - delete m_variable; -} - -void CheckAllocateStatementAST::generate(string& code, Type* return_type_ptr) const -{ - // FIXME - check the type of the variable - - // Make sure the variable is valid - m_variable->getVar(); -} - -void CheckAllocateStatementAST::findResources(Map<Var*, string>& resource_list) const -{ - Var* var_ptr = m_variable->getVar(); - int res_count = 0; - if (resource_list.exist(var_ptr)) { - res_count = atoi((resource_list.lookup(var_ptr)).c_str()); - } - resource_list.add(var_ptr, int_to_string(res_count+1)); -} - -void CheckAllocateStatementAST::print(ostream& out) const -{ - out << "[CheckAllocateStatementAst: " << *m_variable << "]"; -} diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.py b/src/mem/slicc/ast/CheckAllocateStatementAST.py new file mode 100644 index 000000000..b96153b0a --- /dev/null +++ b/src/mem/slicc/ast/CheckAllocateStatementAST.py @@ -0,0 +1,47 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST + +class CheckAllocateStatementAST(StatementAST): + def __init__(self, slicc, variable): + super(StatementAST, self).__init__(slicc) + self.variable = variable + + def __repr__(self): + return "[CheckAllocateStatementAst: %r]" % self.variable + + def generate(self, code, return_type): + # FIXME - check the type of the variable + + # Make sure the variable is valid + self.variable.var + + def findResources(self, resources): + var = self.variable.var + res_count = int(resources.get(var, 0)) + resources[var] = str(res_count + 1) diff --git a/src/mem/slicc/ast/CheckStopSlotsStatementAST.cc b/src/mem/slicc/ast/CheckStopSlotsStatementAST.cc deleted file mode 100644 index 38dc449d6..000000000 --- a/src/mem/slicc/ast/CheckStopSlotsStatementAST.cc +++ /dev/null @@ -1,115 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/ast/CheckStopSlotsStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/PairListAST.hh" - -CheckStopSlotsStatementAST::CheckStopSlotsStatementAST(VarExprAST* variable, string* condStr, string* bankStr) - : StatementAST() -{ - m_variable = variable; - m_condStr_ptr = condStr; - m_bankStr_ptr = bankStr; -} - -CheckStopSlotsStatementAST::~CheckStopSlotsStatementAST() -{ - delete m_variable; - delete m_condStr_ptr; - delete m_bankStr_ptr; -} - -void CheckStopSlotsStatementAST::generate(string& code, Type* return_type_ptr) const -{ - - // Make sure the variable is valid - m_variable->getVar(); - -} - -void CheckStopSlotsStatementAST::findResources(Map<Var*, string>& resource_list) const -{ - Type* type_ptr; - - Var* var_ptr = m_variable->getVar(); - string check_code; - - if (*m_condStr_ptr == "((*in_msg_ptr)).m_isOnChipSearch") { - check_code += " const Response9Msg* in_msg_ptr;\n"; - check_code += " in_msg_ptr = dynamic_cast<const Response9Msg*>(((*(m_chip_ptr->m_L2Cache_responseToL2Cache9_vec[m_version]))).peek());\n"; - check_code += " assert(in_msg_ptr != NULL);\n"; - } - - check_code += " if ("; - check_code += *m_condStr_ptr; - check_code += ") {\n"; - - check_code += " if (!"; - type_ptr = m_variable->generate(check_code); - check_code += ".isDisableSPossible((((*(m_chip_ptr->m_DNUCAmover_ptr))).getBankPos("; - check_code += *m_bankStr_ptr; - check_code += ")))) {\n"; - if(CHECK_INVALID_RESOURCE_STALLS) { - check_code += " assert(priority >= "; - type_ptr = m_variable->generate(check_code); - check_code += ".getPriority());\n"; - } - check_code += " return TransitionResult_ResourceStall;\n"; - check_code += " }\n"; - check_code += " } else {\n"; - check_code += " if (!"; - type_ptr = m_variable->generate(check_code); - check_code += ".isDisableFPossible((((*(m_chip_ptr->m_DNUCAmover_ptr))).getBankPos("; - check_code += *m_bankStr_ptr; - check_code += ")))) {\n"; - if(CHECK_INVALID_RESOURCE_STALLS) { - check_code += " assert(priority >= "; - type_ptr = m_variable->generate(check_code); - check_code += ".getPriority());\n"; - } - check_code += " return TransitionResult_ResourceStall;\n"; - check_code += " }\n"; - check_code += " }\n"; - - assert(!resource_list.exist(var_ptr)); - resource_list.add(var_ptr, check_code); - -} - -void CheckStopSlotsStatementAST::print(ostream& out) const -{ - out << "[CheckStopSlotsStatementAst: " << *m_variable << "]"; -} diff --git a/src/mem/slicc/ast/CheckStopSlotsStatementAST.hh b/src/mem/slicc/ast/CheckStopSlotsStatementAST.hh deleted file mode 100644 index 6de068caa..000000000 --- a/src/mem/slicc/ast/CheckStopSlotsStatementAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#ifndef CHECKSTOPSLOTSSTATEMENTAST_H -#define CHECKSTOPSLOTSSTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class VarExprAST; -class Var; - -class CheckStopSlotsStatementAST : public StatementAST { -public: - // Constructors - CheckStopSlotsStatementAST(VarExprAST* variable, string* condStr, string* bankStr); - - // Destructor - ~CheckStopSlotsStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - CheckStopSlotsStatementAST(const CheckStopSlotsStatementAST& obj); - CheckStopSlotsStatementAST& operator=(const CheckStopSlotsStatementAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_variable; - string* m_condStr_ptr; - string* m_bankStr_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const CheckStopSlotsStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const CheckStopSlotsStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //CHECKSTOPSLOTSSTATEMENTAST_H diff --git a/src/mem/slicc/ast/CheckStopSlotsStatementAST.py b/src/mem/slicc/ast/CheckStopSlotsStatementAST.py new file mode 100644 index 000000000..307fbd6a1 --- /dev/null +++ b/src/mem/slicc/ast/CheckStopSlotsStatementAST.py @@ -0,0 +1,74 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST + +class CheckStopSlotsStatementAST(StatementAST): + def __init__(self, slicc, variable, condStr, bankStr): + super(StatementAST, self).__init__(slicc) + self.variable = variable + self.condStr = condStr + self.bankStr = bankStr + + def __repr__(self): + return "[CheckStopSlotsStatementAst: %r]" % self.variable + + def generate(self, code, return_type): + # Make sure the variable is valid + self.variable.var + + def findResources(self, resources): + var = self.variable.var + assert var not in self.resources + + check_code = code_formatter() + if self.condStr == "((*in_msg_ptr)).m_isOnChipSearch": + check_code(''' +const Response9Msg* in_msg_ptr = + dynamic_cast<const Response9Msg*>(((*(m_chip_ptr.m_L2Cache_responseToL2Cache9_vec[m_version]))).peek()); +assert(in_msg_ptr != NULL); +''') + + vcode = self.variable.inline() + bank = self.bankStr + cond = self.condStr + + check_code(''' +if ($cond) { + auto pos = m_chip_ptr.m_DNUCAmover_ptr->getBankPos($bank) + + if (!$vcode.isDisableSPossible(pos)) { + return TransitionResult_ResourceStall; + } +} else { + if (!$vcode.isDisableFPossible(pos)) { + return TransitionResult_ResourceStall; + } +} +''') + + resources[var] = str(check_code) diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.cc b/src/mem/slicc/ast/ChipComponentAccessAST.cc deleted file mode 100644 index 61dccf2c0..000000000 --- a/src/mem/slicc/ast/ChipComponentAccessAST.cc +++ /dev/null @@ -1,244 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ChipComponentAccessAST.C - * - * Description: See ChipComponentAccessAST.hh - * - * $Id: ChipComponentAccessAST.C 1.9 04/06/18 21:00:08-00:00 beckmann@cottons.cs.wisc.edu $ - * - */ - -#include "mem/slicc/ast/ChipComponentAccessAST.hh" - -ChipComponentAccessAST::ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector<ExprAST*>* expr_vec_ptr) - - : ExprAST() -{ - m_chip_ver_expr_ptr = NULL; - m_mach_var_ptr = machine; - m_comp_var_ptr = component; - m_mach_ver_expr_ptr = mach_version; - m_expr_vec_ptr = expr_vec_ptr; - m_proc_name_ptr = proc_name; - m_field_name_ptr = NULL; -} - -ChipComponentAccessAST::ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name) - - : ExprAST() -{ - m_chip_ver_expr_ptr = NULL; - m_mach_var_ptr = machine; - m_comp_var_ptr = component; - m_mach_ver_expr_ptr = mach_version; - m_expr_vec_ptr = NULL; - m_proc_name_ptr = NULL; - m_field_name_ptr = field_name; -} - -ChipComponentAccessAST::ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector<ExprAST*>* expr_vec_ptr) - - : ExprAST() -{ - m_chip_ver_expr_ptr = chip_version; - m_mach_var_ptr = machine; - m_comp_var_ptr = component; - m_mach_ver_expr_ptr = mach_version; - m_expr_vec_ptr = expr_vec_ptr; - m_proc_name_ptr = proc_name; - m_field_name_ptr = NULL; -} - -ChipComponentAccessAST::ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name) - - : ExprAST() -{ - m_chip_ver_expr_ptr = chip_version; - m_mach_var_ptr = machine; - m_comp_var_ptr = component; - m_mach_ver_expr_ptr = mach_version; - m_expr_vec_ptr = NULL; - m_proc_name_ptr = NULL; - m_field_name_ptr = field_name; -} - - - -ChipComponentAccessAST::~ChipComponentAccessAST() -{ - if (m_expr_vec_ptr != NULL) { - int size = m_expr_vec_ptr->size(); - for(int i=0; i<size; i++) { - delete (*m_expr_vec_ptr)[i]; - } - } - - delete m_mach_var_ptr; - delete m_comp_var_ptr; - delete m_mach_ver_expr_ptr; - - if (m_proc_name_ptr != NULL) { - delete m_proc_name_ptr; - } - - if (m_field_name_ptr != NULL) { - delete m_field_name_ptr; - } - - if (m_chip_ver_expr_ptr != NULL) { - delete m_chip_ver_expr_ptr; - } -} - -Type* ChipComponentAccessAST::generate(string& code) const -{ - Type* void_type_ptr = g_sym_table.getType("void"); - Type* ret_type_ptr; - - - code += "("; - - Var* v = g_sym_table.getMachComponentVar(m_mach_var_ptr->getName(), m_comp_var_ptr->getName()); - - string orig_code = v->getCode(); - string working_code; - - if (m_chip_ver_expr_ptr != NULL) { - // replace m_chip_ptr with specified chip - - unsigned int t = orig_code.find("m_chip_ptr"); - assert(t != string::npos); - string code_temp0 = orig_code.substr(0, t); - string code_temp1 = orig_code.substr(t+10); - - working_code += code_temp0; - working_code += "g_system_ptr->getChip("; - m_chip_ver_expr_ptr->generate(working_code); - working_code += ")"; - working_code += code_temp1; - } - else { - working_code += orig_code; - } - - // replace default "m_version" with the version we really want - unsigned int tmp_uint = working_code.find("m_version"); - assert(tmp_uint != string::npos); - string code_temp2 = working_code.substr(0, tmp_uint); - string code_temp3 = working_code.substr(tmp_uint+9); - - code += code_temp2; - code += "("; - m_mach_ver_expr_ptr->generate(code); - code += ")"; - code += code_temp3; - code += ")"; - - if (m_proc_name_ptr != NULL) { - // method call - code += "."; - - Vector <Type*> paramTypes; - - // generate code - int actual_size = m_expr_vec_ptr->size(); - code += (*m_proc_name_ptr) + "("; - for(int i=0; i<actual_size; i++) { - if (i != 0) { - code += ", "; - } - // Check the types of the parameter - Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(code); - paramTypes.insertAtBottom(actual_type_ptr); - } - code += ")"; - - Type* obj_type_ptr = v->getType(); - string methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes); - - // Verify that this is a method of the object - if (!obj_type_ptr->methodExist(methodId)) { - error("Invalid method call: Type '" + obj_type_ptr->toString() + "' does not have a method '" + methodId + "'"); - } - - int expected_size = obj_type_ptr->methodParamType(methodId).size(); - if (actual_size != expected_size) { - // Right number of parameters - ostringstream err; - err << "Wrong number of parameters for function name: '" << *m_proc_name_ptr << "'"; - err << ", expected: "; - err << expected_size; - err << ", actual: "; - err << actual_size; - error(err.str()); - } - - for(int i=0; i<actual_size; i++) { - // Check the types of the parameter - Type* actual_type_ptr = paramTypes[i]; - Type* expected_type_ptr = obj_type_ptr->methodParamType(methodId)[i]; - if (actual_type_ptr != expected_type_ptr) { - (*m_expr_vec_ptr)[i]->error("Type mismatch: expected: " + expected_type_ptr->toString() + - " actual: " + actual_type_ptr->toString()); - } - } - - // Return the return type of the method - ret_type_ptr = obj_type_ptr->methodReturnType(methodId); - } - else if (m_field_name_ptr != NULL) { - Type* obj_type_ptr = v->getType(); - code += ").m_" + (*m_field_name_ptr); - - // Verify that this is a valid field name for this type - if (!obj_type_ptr->dataMemberExist(*m_field_name_ptr)) { - error("Invalid object field: Type '" + obj_type_ptr->toString() + "' does not have data member " + *m_field_name_ptr); - } - - // Return the type of the field - ret_type_ptr = obj_type_ptr->dataMemberType(*m_field_name_ptr); - } - else { - assert(0); - } - - return ret_type_ptr; -} - -void ChipComponentAccessAST::findResources(Map<Var*, string>& resource_list) const -{ - -} - -void ChipComponentAccessAST::print(ostream& out) const -{ - out << "[ChipAccessExpr: " << *m_expr_vec_ptr << "]"; -} diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.hh b/src/mem/slicc/ast/ChipComponentAccessAST.hh deleted file mode 100644 index 1f22a79e4..000000000 --- a/src/mem/slicc/ast/ChipComponentAccessAST.hh +++ /dev/null @@ -1,101 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * - * - * Description: - * - * $Id: ChipComponentAccessAST.hh 1.8 04/06/18 21:00:08-00:00 beckmann@cottons.cs.wisc.edu $ - * - */ - -#ifndef ChipComponentAccessAST_H -#define ChipComponentAccessAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class ChipComponentAccessAST : public ExprAST { -public: - // Constructors - - // method call from local chip - ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector<ExprAST*>* expr_vec_ptr); - // member access from local chip - ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name); - - // method call from specified chip - ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector<ExprAST*>* expr_vec_ptr); - - // member access from specified chip - ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name); - - // Destructor - ~ChipComponentAccessAST(); - - // Public Methods - Type* generate(string& code) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ChipComponentAccessAST(const ChipComponentAccessAST& obj); - ChipComponentAccessAST& operator=(const ChipComponentAccessAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_mach_var_ptr; - VarExprAST* m_comp_var_ptr; - ExprAST* m_mach_ver_expr_ptr; - ExprAST* m_chip_ver_expr_ptr; - Vector<ExprAST*>* m_expr_vec_ptr; - string* m_proc_name_ptr; - string* m_field_name_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ChipComponentAccessAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ChipComponentAccessAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif // ChipComponentAccessAST_H diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.py b/src/mem/slicc/ast/ChipComponentAccessAST.py new file mode 100644 index 000000000..bbb1b61e9 --- /dev/null +++ b/src/mem/slicc/ast/ChipComponentAccessAST.py @@ -0,0 +1,161 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import re + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Type + +class ChipComponentAccessAST(ExprAST): + def __init__(self, slicc, machine, mach_version, component): + super(ChipComponentAccessAST, self).__init__(slicc) + self.mach_var = machine + self.comp_var = component + self.mach_ver_expr = mach_version + + def __repr__(self): + return "[ChipAccessExpr: %r]" % self.expr_vec + + def generate(self, code): + void_type = self.symtab.find("void", Type) + + mname = self.mach_var.name + cname = self.comp_var.name + var = self.symtab.machine_components[mname][cname] + + vcode = str(var.code) + + if self.chip_ver_expr is not None: + # replace self.chip with specified chip + gcode = "g_system.getChip(%s)" % self.chip_ver_expr.inline() + vcode = re.sub("m_chip", gcode, vcode) + + # replace default "m_version" with the version we really want + gcode = "(%s)" % self.mach_ver_expr.inline() + vcode = re.sub("m_version", gcode, vcode) + + return_type, gcode = self.generate_access(var) + code("($vcode)$gcode") + return return_type + +class ChipMethodAccessAST(ChipComponentAccessAST): + def __init__(self, slicc, chip_version, machine, mach_version, component, + proc_name, expr_vec): + s = super(ChipMethodAccessAST, self) + s.__init__(slicc, machine, mach_version, component) + + self.chip_ver_expr = chip_version + self.expr_vec = expr_vec + self.proc_name = proc_name + + def generate_access(self, var): + # generate code + paramTypes = [] + gcode = [] + for expr in self.expr_vec: + t,c = expr.generate() + paramTypes.append(t) + gcode.append(c) + + methodId = var.type.methodId(self.proc_name, paramTypes) + + # Verify that this is a method of the object + if not var.type.methodExist(methodId): + self.error("%s: Type '%s' does not have a method '%s'" % \ + ("Invalid method call", var.type, methodId)) + + expected_size = len(var.type.methodParamType(methodId)) + if len(self.expr_vec) != expected_size: + # Right number of parameters + self.error("Wrong number of parameters for function name: " +\ + "'%s', expected: %d, actual: %d", + self.proc_name, expected_size, len(self.expr_vec)) + + for expr,expected,actual in zip(self.expr_vec, + var.type.methodParamType(methodId), + paramTypes): + # Check the types of the parameter + if actual != expected: + expr.error("Type mismatch: expected: %s actual: %s", + expected, actual) + + # method call + code = ".%s(%s)" % (self.proc_name, ', '.join(gcode)) + + # Return the return type of the method + return var.type.methodReturnType(methodId), code + +class LocalChipMethodAST(ChipMethodAccessAST): + # method call from local chip + def __init__(self, slicc, machine, mach_version, component, proc_name, + expr_vec): + s = super(LocalChipMethodAST, self) + s.__init__(slicc, None, machine, mach_version, component, proc_name, + expr_vec) + +class SpecifiedChipMethodAST(ChipMethodAccessAST): + # method call from specified chip + def __init__(self, slicc, chip_version, machine, mach_version, component, + proc_name, expr_vec): + s = super(SpecifiedChipMethodAST, self) + s.__init__(slicc, chip_version, machine, mach_version, component, + proc_name, expr_vec) + +class ChipMemberAccessAST(ChipComponentAccessAST): + # member access from specified chip + def __init__(self, chip_version, machine, mach_version, component, + field_name): + s = super(ChipMemberAccessAST, self) + s.__init__(slicc, machine, mach_version, component) + + self.chip_ver_expr = chip_version + self.field_name = field_name + + def generate_access(self, var): + # Verify that this is a valid field name for this type + if not var.type.dataMemberExist(self.field_name): + self.error("Invalid object field: " +\ + "Type '%s' does not have data member %s", + var.type, self.field_name) + + code += ").m_%s" % self.field_name + + return var.type.dataMemberType(self.field_name), code + +class LocalChipMemberAST(ChipMemberAccessAST): + # member access from local chip + def __init__(self, slicc, machine, mach_version, component, field_name): + s = super(LocalChipMemberAST, self) + s.__init__(slicc, None, machine, mach_version, component, field_name) + +class SpecifiedChipMemberAST(ChipMemberAccessAST): + # member access from specified chip + def __init__(self, chip_version, machine, mach_version, component, + field_name): + s = super(SpecifiedChipMemberAST, self) + s.__init__(slicc, chip_version, machine, mach_version, component, + field_name) diff --git a/src/mem/slicc/ast/CopyHeadStatementAST.cc b/src/mem/slicc/ast/CopyHeadStatementAST.cc deleted file mode 100644 index 8d455eb9d..000000000 --- a/src/mem/slicc/ast/CopyHeadStatementAST.cc +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/ast/CopyHeadStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/gems_common/util.hh" - -CopyHeadStatementAST::CopyHeadStatementAST(VarExprAST* in_queue_ptr, - VarExprAST* out_queue_ptr, - PairListAST* pairs_ptr) - : StatementAST(pairs_ptr->getPairs()) -{ - m_in_queue_ptr = in_queue_ptr; - m_out_queue_ptr = out_queue_ptr; -} - -CopyHeadStatementAST::~CopyHeadStatementAST() -{ - delete m_in_queue_ptr; - delete m_out_queue_ptr; -} - -void CopyHeadStatementAST::generate(string& code, Type* return_type_ptr) const -{ - m_in_queue_ptr->assertType("InPort"); - m_out_queue_ptr->assertType("OutPort"); - - code += indent_str(); - code += m_out_queue_ptr->getVar()->getCode() + ".enqueue(" + m_in_queue_ptr->getVar()->getCode() + ".getMsgPtrCopy()"; - - if (getPairs().exist("latency")) { - code += ", " + getPairs().lookup("latency"); - } else { - code += ", COPY_HEAD_LATENCY"; - } - - code += ");\n"; -} - -void CopyHeadStatementAST::findResources(Map<Var*, string>& resource_list) const -{ - Var* var_ptr = m_out_queue_ptr->getVar(); - int res_count = 0; - if (resource_list.exist(var_ptr)) { - res_count = atoi((resource_list.lookup(var_ptr)).c_str()); - } - resource_list.add(var_ptr, int_to_string(res_count+1)); -} - -void CopyHeadStatementAST::print(ostream& out) const -{ - out << "[CopyHeadStatementAst: " << *m_in_queue_ptr << " " << *m_out_queue_ptr << "]"; -} diff --git a/src/mem/slicc/ast/CopyHeadStatementAST.hh b/src/mem/slicc/ast/CopyHeadStatementAST.hh deleted file mode 100644 index 53d479136..000000000 --- a/src/mem/slicc/ast/CopyHeadStatementAST.hh +++ /dev/null @@ -1,87 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#ifndef COPYHEADSTATEMENTAST_H -#define COPYHEADTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/PairListAST.hh" - -class VarExprAST; -class Var; - -class CopyHeadStatementAST : public StatementAST { -public: - // Constructors - CopyHeadStatementAST(VarExprAST* in_queue_ptr, - VarExprAST* out_queue_ptr, - PairListAST* pairs_ptr); - - // Destructor - ~CopyHeadStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - CopyHeadStatementAST(const CopyHeadStatementAST& obj); - CopyHeadStatementAST& operator=(const CopyHeadStatementAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_in_queue_ptr; - VarExprAST* m_out_queue_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const CopyHeadStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const CopyHeadStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //COPYHEADSTATEMENTAST_H diff --git a/src/mem/slicc/ast/CopyHeadStatementAST.py b/src/mem/slicc/ast/CopyHeadStatementAST.py new file mode 100644 index 000000000..ba9970975 --- /dev/null +++ b/src/mem/slicc/ast/CopyHeadStatementAST.py @@ -0,0 +1,52 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST + +class CopyHeadStatementAST(StatementAST): + def __init__(self, slicc, in_queue, out_queue, pairs): + super(CopyHeadStatementAST, self).__init__(slicc, pairs) + + self.in_queue = in_queue + self.out_queue_ptr = out_queue + + def __repr__(self): + return "[CopyHeadStatementAst: %r %r]" % (self.in_queue, + self.out_queue) + + def generate(self, code, return_type): + self.in_queue.assertType("InPort") + self.out_queue.assertType("OutPort") + + out_code = self.out_queue.var.code + in_code = self.in_queue.var.code + latency = self.get("latency", "COPY_HEAD_LATENCY") + code("$out_code.enqueue($in_code.getMsgPtrCopy(), $latency);") + + def findResources(self, resources): + var = self.out_queue.var + resources[var] = str(int(resources.get(var, "0")) + 1) diff --git a/src/mem/slicc/ast/DeclAST.py b/src/mem/slicc/ast/DeclAST.py new file mode 100644 index 000000000..1adb31321 --- /dev/null +++ b/src/mem/slicc/ast/DeclAST.py @@ -0,0 +1,38 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class DeclAST(AST): + def __init__(self, slicc, pairs): + super(DeclAST, self).__init__(slicc, pairs) + + def files(self, parent=None): + return set() + + def findMachines(self): + return diff --git a/src/mem/slicc/ast/DeclListAST.hh b/src/mem/slicc/ast/DeclListAST.hh deleted file mode 100644 index 1c2bc3c05..000000000 --- a/src/mem/slicc/ast/DeclListAST.hh +++ /dev/null @@ -1,84 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * DeclListAST.hh - * - * Description: - * - * $Id: DeclListAST.hh,v 3.1 2001/12/12 01:00:12 milo Exp $ - * - */ - -#ifndef DeclListAST_H -#define DeclListAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" -#include "mem/slicc/ast/DeclAST.hh" - -class DeclListAST : public AST { -public: - // Constructors - DeclListAST(Vector<DeclAST*>* vec_ptr); - DeclListAST(DeclAST* statement_ptr); - - // Destructor - ~DeclListAST(); - - // Public Methods - void generate() const; - void findMachines() const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - DeclListAST(const DeclListAST& obj); - DeclListAST& operator=(const DeclListAST& obj); - - // Data Members (m_ prefix) - Vector<DeclAST*>* m_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const DeclListAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const DeclListAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //DeclListAST_H diff --git a/src/mem/slicc/ast/DeclListAST.py b/src/mem/slicc/ast/DeclListAST.py new file mode 100644 index 000000000..36c520070 --- /dev/null +++ b/src/mem/slicc/ast/DeclListAST.py @@ -0,0 +1,53 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class DeclListAST(AST): + def __init__(self, slicc, decls): + super(DeclListAST, self).__init__(slicc) + + if not isinstance(decls, (list, tuple)): + decls = [ decls ] + self.decls = decls + + def __repr__(self): + return "[DeclListAST: %s]" % (', '.join(repr(d) for d in self.decls)) + + def files(self, parent=None): + s = set() + for decl in self.decls: + s |= decl.files(parent) + return s + + def generate(self): + for decl in self.decls: + decl.generate() + + def findMachines(self): + for decl in self.decls: + decl.findMachines() diff --git a/src/mem/slicc/ast/EnqueueStatementAST.cc b/src/mem/slicc/ast/EnqueueStatementAST.cc deleted file mode 100644 index a422d8a28..000000000 --- a/src/mem/slicc/ast/EnqueueStatementAST.cc +++ /dev/null @@ -1,111 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/ast/EnqueueStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/PairListAST.hh" -#include "mem/gems_common/util.hh" - -EnqueueStatementAST::EnqueueStatementAST(VarExprAST* queue_name_ptr, - TypeAST* type_name_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ast_ptr) - : StatementAST(pairs_ptr->getPairs()) -{ - m_queue_name_ptr = queue_name_ptr; - m_type_name_ptr = type_name_ptr; - m_statement_list_ast_ptr = statement_list_ast_ptr; -} - -EnqueueStatementAST::~EnqueueStatementAST() -{ - delete m_queue_name_ptr; - delete m_type_name_ptr; - delete m_statement_list_ast_ptr; -} - -void EnqueueStatementAST::generate(string& code, Type* return_type_ptr) const -{ - code += indent_str() + "{\n"; // Start scope - inc_indent(); - g_sym_table.pushFrame(); - - Type* msg_type_ptr = m_type_name_ptr->lookupType(); - - // Add new local var to symbol table - g_sym_table.newSym(new Var("out_msg", getLocation(), msg_type_ptr, "out_msg", getPairs())); - - code += indent_str() + msg_type_ptr->cIdent() + " out_msg;\n"; // Declare message - m_statement_list_ast_ptr->generate(code, NULL); // The other statements - - code += indent_str(); - - m_queue_name_ptr->assertType("OutPort"); - code += "(" + m_queue_name_ptr->getVar()->getCode() + ")"; - code += ".enqueue(out_msg"; - - if (getPairs().exist("latency")) { - bool is_number = true; - string val = getPairs().lookup("latency"); - for (int i=0; i<val.size(); i++) - if (!isdigit(val[i])) is_number = false; - if (is_number) - code += ", " + getPairs().lookup("latency"); - else - code += ", m_" + getPairs().lookup("latency"); - } - - code += ");\n"; - - dec_indent(); - g_sym_table.popFrame(); - code += indent_str() + "}\n"; // End scope -} - -void EnqueueStatementAST::findResources(Map<Var*, string>& resource_list) const -{ - Var* var_ptr = m_queue_name_ptr->getVar(); - int res_count = 0; - if (resource_list.exist(var_ptr)) { - res_count = atoi((resource_list.lookup(var_ptr)).c_str()); - } - resource_list.add(var_ptr, int_to_string(res_count+1)); -} - -void EnqueueStatementAST::print(ostream& out) const -{ - out << "[EnqueueStatementAst: " << *m_queue_name_ptr << " " - << m_type_name_ptr->toString() << " " << *m_statement_list_ast_ptr << "]"; -} diff --git a/src/mem/slicc/ast/EnqueueStatementAST.hh b/src/mem/slicc/ast/EnqueueStatementAST.hh deleted file mode 100644 index fc2776ed7..000000000 --- a/src/mem/slicc/ast/EnqueueStatementAST.hh +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnqueueStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef ENQUEUESTATEMENTAST_H -#define ENQUEUESTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class VarExprAST; -class Var; -class PairListAST; - -class EnqueueStatementAST : public StatementAST { -public: - // Constructors - EnqueueStatementAST(VarExprAST* queue_name_ptr, - TypeAST* type_name_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ast_ptr); - - // Destructor - ~EnqueueStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - EnqueueStatementAST(const EnqueueStatementAST& obj); - EnqueueStatementAST& operator=(const EnqueueStatementAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_queue_name_ptr; - TypeAST* m_type_name_ptr; - StatementListAST* m_statement_list_ast_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const EnqueueStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const EnqueueStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ENQUEUESTATEMENTAST_H diff --git a/src/mem/slicc/ast/EnqueueStatementAST.py b/src/mem/slicc/ast/EnqueueStatementAST.py new file mode 100644 index 000000000..faf966460 --- /dev/null +++ b/src/mem/slicc/ast/EnqueueStatementAST.py @@ -0,0 +1,86 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST +from slicc.symbols import Var + +class EnqueueStatementAST(StatementAST): + def __init__(self, slicc, queue_name, type_ast, pairs, statements): + super(EnqueueStatementAST, self).__init__(slicc, pairs) + + self.queue_name = queue_name + self.type_ast = type_ast + self.statements = statements + + def __repr__(self): + return "[EnqueueStatementAst: %s %s %s]" % \ + (self.queue_name, self.type_ast.ident, self.statements) + + def generate(self, code, return_type): + code("{") + code.indent() + self.symtab.pushFrame() + + msg_type = self.type_ast.type + + # Add new local var to symbol table + v = Var(self.symtab, "out_msg", self.location, msg_type, "out_msg", + self.pairs) + self.symtab.newSymbol(v) + + # Declare message + code("${{msg_type.ident}} out_msg;") + + # The other statements + t = self.statements.generate(code, None) + + self.queue_name.assertType("OutPort") + + args = [ "out_msg" ] + if "latency" in self: + latency = self["latency"] + try: + # see if this is an integer + latency = int(latency) + args.append("%s" % latency) + except ValueError: + # if not, it should be a member + args.append("m_%s" % latency) + + args = ", ".join(args) + code('(${{self.queue_name.var.code}}).enqueue($args);') + + + # End scope + self.symtab.popFrame() + code.dedent() + code("}") + + def findResources(self, resources): + var = self.queue_name.var + res_count = int(resources.get(var, 0)) + resources[var] = str(res_count + 1) diff --git a/src/mem/slicc/ast/EnumDeclAST.cc b/src/mem/slicc/ast/EnumDeclAST.cc deleted file mode 100644 index b051f3c8f..000000000 --- a/src/mem/slicc/ast/EnumDeclAST.cc +++ /dev/null @@ -1,98 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnumDeclAST.C - * - * Description: See EnumDeclAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/EnumDeclAST.hh" -#include "mem/slicc/main.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -EnumDeclAST::EnumDeclAST(TypeAST* type_ast_ptr, - PairListAST* pairs_ptr, - Vector<TypeFieldAST*>* field_vec_ptr) - : DeclAST(pairs_ptr) -{ - m_type_ast_ptr = type_ast_ptr; - m_field_vec_ptr = field_vec_ptr; -} - -EnumDeclAST::~EnumDeclAST() -{ - delete m_type_ast_ptr; - if (m_field_vec_ptr != NULL) { - int size = m_field_vec_ptr->size(); - for(int i=0; i<size; i++) { - delete (*m_field_vec_ptr)[i]; - } - delete m_field_vec_ptr; - } -} - -void EnumDeclAST::generate() -{ - string machine_name; - string id = m_type_ast_ptr->toString(); - - Vector<Type*> param_type_vec; // used by to_string func call - - // Make the new type - Type* new_type_ptr = new Type(id, getLocation(), getPairs(), - g_sym_table.getStateMachine()); - g_sym_table.newSym(new_type_ptr); - - // Add all of the fields of the type to it - if (m_field_vec_ptr != NULL) { - int size = m_field_vec_ptr->size(); - for(int i=0; i<size; i++) { - (*m_field_vec_ptr)[i]->generate(new_type_ptr); - } - } - - // Add the implicit State_to_string method - FIXME, this is a bit dirty - param_type_vec.insertAtBottom(new_type_ptr); // add state to param vector - string func_id = new_type_ptr->cIdent()+"_to_string"; - - Map<string, string> pairs; - pairs.add("external", "yes"); - Vector<string> string_vec; - g_sym_table.newSym(new Func(func_id, getLocation(), g_sym_table.getType("string"), param_type_vec, string_vec, string(""), pairs, NULL)); -} - -void EnumDeclAST::print(ostream& out) const -{ - out << "[EnumDecl: " << m_type_ast_ptr->toString() << "]"; -} - diff --git a/src/mem/slicc/ast/EnumDeclAST.hh b/src/mem/slicc/ast/EnumDeclAST.hh deleted file mode 100644 index 2af650e83..000000000 --- a/src/mem/slicc/ast/EnumDeclAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnummDeclAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef EnumDeclAST_H -#define EnumDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" - -class EnumDeclAST : public DeclAST { -public: - // Constructors - EnumDeclAST(TypeAST* type_ast_ptr, - PairListAST* pairs_ptr, - Vector<TypeFieldAST*>* field_vec_ptr); - - // Destructor - ~EnumDeclAST(); - - // Public Methods - virtual void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - EnumDeclAST(const EnumDeclAST& obj); - EnumDeclAST& operator=(const EnumDeclAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_type_ast_ptr; - Vector<TypeFieldAST*>* m_field_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const EnumDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const EnumDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //EnumDeclAST_H diff --git a/src/mem/slicc/ast/EnumDeclAST.py b/src/mem/slicc/ast/EnumDeclAST.py new file mode 100644 index 000000000..a20f4b749 --- /dev/null +++ b/src/mem/slicc/ast/EnumDeclAST.py @@ -0,0 +1,71 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Func, Type + +class EnumDeclAST(DeclAST): + def __init__(self, slicc, type_ast, pairs, fields): + super(EnumDeclAST, self).__init__(slicc, pairs) + + self.type_ast = type_ast + self.fields = fields + + def __repr__(self): + return "[EnumDecl: %s]" % (self.type_ast) + + def files(self, parent=None): + if "external" in self: + return set() + + if parent: + ident = "%s_%s" % (parent, self.type_ast.ident) + else: + ident = self.type_ast.ident + s = set(("%s.hh" % ident, "%s.cc" % ident)) + return s + + def generate(self): + ident = str(self.type_ast) + + # Make the new type + t = Type(self.symtab, ident, self.location, self.pairs, + self.state_machine) + self.symtab.newSymbol(t) + + # Add all of the fields of the type to it + for field in self.fields: + field.generate(t) + + # Add the implicit State_to_string method - FIXME, this is a bit dirty + func_id = "%s_to_string" % t.c_ident + + pairs = { "external" : "yes" } + func = Func(self.symtab, func_id, self.location, + self.symtab.find("string", Type), [ t ], [], "", + pairs, None) + self.symtab.newSymbol(func) diff --git a/src/mem/slicc/ast/EnumExprAST.hh b/src/mem/slicc/ast/EnumExprAST.hh deleted file mode 100644 index 8af1c8891..000000000 --- a/src/mem/slicc/ast/EnumExprAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnumExprAST.hh - * - * Description: - * - * $Id: EnumExprAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef EnumExprAST_H -#define EnumExprAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - - -class EnumExprAST : public ExprAST { -public: - // Constructors - EnumExprAST(TypeAST* type_ast_ptr, - string* value_ptr); - - // Destructor - ~EnumExprAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - EnumExprAST(const EnumExprAST& obj); - EnumExprAST& operator=(const EnumExprAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_type_ast_ptr; - string* m_value_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const EnumExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const EnumExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //EnumExprAST_H diff --git a/src/mem/slicc/ast/EnumExprAST.py b/src/mem/slicc/ast/EnumExprAST.py new file mode 100644 index 000000000..9cb76a8a1 --- /dev/null +++ b/src/mem/slicc/ast/EnumExprAST.py @@ -0,0 +1,53 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST + +class EnumExprAST(ExprAST): + def __init__(self, slicc, type_ast, value): + super(EnumExprAST, self).__init__(slicc) + + assert type_ast + assert value + + self.type_ast = type_ast + self.value = value + + def __repr__(self): + return "[EnumExpr: %s:%s]" % (self.type_ast, self.value) + + def generate(self, code): + fix = code.nofix() + code('${{self.type_ast.type.c_ident}}_${{self.value}}') + code.fix(fix) + + # Make sure the enumeration value exists + if self.value not in self.type_ast.type.enums: + self.error("Type '%s' does not have enumeration '%s'", + self.type_ast, self.value) + + return self.type_ast.type diff --git a/src/mem/slicc/ast/ExprAST.cc b/src/mem/slicc/ast/ExprAST.cc deleted file mode 100644 index 3427d4dd9..000000000 --- a/src/mem/slicc/ast/ExprAST.cc +++ /dev/null @@ -1,39 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ExprAST.C - * - * Description: See ExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/ExprAST.hh" diff --git a/src/mem/slicc/ast/ExprAST.py b/src/mem/slicc/ast/ExprAST.py new file mode 100644 index 000000000..70a0aa0b5 --- /dev/null +++ b/src/mem/slicc/ast/ExprAST.py @@ -0,0 +1,45 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.AST import AST + +class ExprAST(AST): + def __init__(self, slicc): + super(ExprAST, self).__init__(slicc) + + def findResources(self, resources): + # The default is no resources + pass + + def inline(self, get_type=False): + code = code_formatter(fix_newlines=False) + return_type = self.generate(code) + if get_type: + return return_type, code + else: + return code diff --git a/src/mem/slicc/ast/ExprStatementAST.hh b/src/mem/slicc/ast/ExprStatementAST.hh deleted file mode 100644 index a47e86af5..000000000 --- a/src/mem/slicc/ast/ExprStatementAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ExprStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef ExprStatementAST_H -#define ExprStatementAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - -class ExprStatementAST : public StatementAST { -public: - // Constructors - ExprStatementAST(ExprAST* expr_ptr); - - // Destructor - ~ExprStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ExprStatementAST(const ExprStatementAST& obj); - ExprStatementAST& operator=(const ExprStatementAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_expr_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ExprStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ExprStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ExprStatementAST_H diff --git a/src/mem/slicc/ast/ExprStatementAST.py b/src/mem/slicc/ast/ExprStatementAST.py new file mode 100644 index 000000000..b16d1d072 --- /dev/null +++ b/src/mem/slicc/ast/ExprStatementAST.py @@ -0,0 +1,52 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.StatementAST import StatementAST +from slicc.symbols import Type + +class ExprStatementAST(StatementAST): + def __init__(self, slicc, expr): + super(ExprStatementAST, self).__init__(slicc) + self.expr = expr + + def __repr__(self): + return "[ExprStatementAST: %s]" % (self.expr) + + def generate(self, code, return_type): + actual_type,rcode = self.expr.inline(True) + code("$rcode;") + + # The return type must be void + if actual_type != self.symtab.find("void", Type): + self.expr.error("Non-void return must not be ignored, " + \ + "return type is '%s'", actual_type.ident) + + def findResources(self, resources): + self.expr.findResources(resources) + diff --git a/src/mem/slicc/ast/FormalParamAST.cc b/src/mem/slicc/ast/FormalParamAST.cc deleted file mode 100644 index 529811f25..000000000 --- a/src/mem/slicc/ast/FormalParamAST.cc +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FormalParamAST.C - * - * Description: See FormalParamAST.hh - * - * $Id: FormalParamAST.C,v 3.1 2000/10/05 21:22:20 milo Exp $ - * - */ - -#include "mem/slicc/ast/FormalParamAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -FormalParamAST::~FormalParamAST() -{ - delete m_ident_ptr; - delete m_type_ast_ptr; -} - -string FormalParamAST::getTypeName() const -{ - return m_type_ast_ptr->toString(); -} - -Type* FormalParamAST::getType() const -{ - return m_type_ast_ptr->lookupType(); -} - -Type* FormalParamAST::generate(string& code) const -{ - string param = "param_" + *m_ident_ptr; - - Type* type_ptr = m_type_ast_ptr->lookupType(); - code += type_ptr->cIdent(); - code += " "; - code += param; - - // Add to symbol table - g_sym_table.newSym(new Var(*m_ident_ptr, getLocation(), type_ptr, param, getPairs())); - return type_ptr; -} diff --git a/src/mem/slicc/ast/FormalParamAST.hh b/src/mem/slicc/ast/FormalParamAST.hh deleted file mode 100644 index ca27948b7..000000000 --- a/src/mem/slicc/ast/FormalParamAST.hh +++ /dev/null @@ -1,88 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FormalParamAST.hh - * - * Description: - * - * $Id: FormalParamAST.hh,v 3.1 2001/12/12 01:00:15 milo Exp $ - * - */ - -#ifndef FORMALPARAMAST_H -#define FORMALPARAMAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" - -class TypeAST; - - -class FormalParamAST : public AST { -public: - // Constructors - FormalParamAST(TypeAST* type_ast_ptr, string* ident_ptr) : AST() { m_type_ast_ptr = type_ast_ptr; m_ident_ptr = ident_ptr; } - - // Destructor - ~FormalParamAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const { out << "[FormalParamAST: " << *m_ident_ptr << "]"; } - string getName() const { return *m_ident_ptr; } - string getTypeName() const; - Type* getType() const; -private: - // Private Methods - - // Private copy constructor and assignment operator - FormalParamAST(const FormalParamAST& obj); - FormalParamAST& operator=(const FormalParamAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_type_ast_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const FormalParamAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const FormalParamAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //FORMALPARAMAST_H diff --git a/src/mem/slicc/ast/FormalParamAST.py b/src/mem/slicc/ast/FormalParamAST.py new file mode 100644 index 000000000..b169cbb1c --- /dev/null +++ b/src/mem/slicc/ast/FormalParamAST.py @@ -0,0 +1,52 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST +from slicc.symbols import Var + +class FormalParamAST(AST): + def __init__(self, slicc, type_ast, ident): + super(FormalParamAST, self).__init__(slicc) + self.type_ast = type_ast + self.ident = ident + + def __repr__(self): + return "[FormalParamAST: %s]" % self.ident + + @property + def name(self): + return self.ident + + def generate(self): + type = self.type_ast.type + param = "param_%s" % self.ident + + # Add to symbol table + v = Var(self.symtab, self.ident, self.location, type, param, + self.pairs) + self.symtab.newSymbol(v) + return type, "%s %s" % (type.c_ident, param) diff --git a/src/mem/slicc/ast/FuncCallExprAST.cc b/src/mem/slicc/ast/FuncCallExprAST.cc deleted file mode 100644 index 5b19017e9..000000000 --- a/src/mem/slicc/ast/FuncCallExprAST.cc +++ /dev/null @@ -1,224 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FuncCallExprAST.C - * - * Description: See FuncCallExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/FuncCallExprAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -FuncCallExprAST::FuncCallExprAST(string* proc_name_ptr, - Vector<ExprAST*>* expr_vec_ptr) - : ExprAST() -{ - m_proc_name_ptr = proc_name_ptr; - m_expr_vec_ptr = expr_vec_ptr; -} - -FuncCallExprAST::~FuncCallExprAST() -{ - delete m_proc_name_ptr; - int size = m_expr_vec_ptr->size(); - for(int i=0; i<size; i++) { - delete (*m_expr_vec_ptr)[i]; - } - delete m_expr_vec_ptr; -} - -Type* FuncCallExprAST::generate(string& code) const -{ - // DEBUG_EXPR is strange since it takes parameters of multiple types - if (*m_proc_name_ptr == "DEBUG_EXPR") { - // FIXME - check for number of parameters - code += "DEBUG_SLICC(MedPrio, \""; - code += (*m_expr_vec_ptr)[0]->getLocation().toString(); - code += ": \", "; - (*m_expr_vec_ptr)[0]->generate(code); - code += ");\n"; - Type* void_type_ptr = g_sym_table.getType("void"); - assert(void_type_ptr != NULL); - return void_type_ptr; - } - - // hack for adding comments to profileTransition - if (*m_proc_name_ptr == "APPEND_TRANSITION_COMMENT") { - // FIXME - check for number of parameters - code += "APPEND_TRANSITION_COMMENT("; - //code += (*m_expr_vec_ptr)[0]->getLocation().toString(); - //code += ": \", "; - (*m_expr_vec_ptr)[0]->generate(code); - code += ");\n"; - Type* void_type_ptr = g_sym_table.getType("void"); - assert(void_type_ptr != NULL); - return void_type_ptr; - } - - // Look up the function in the symbol table - Vector<string> code_vec; - Func* func_ptr = g_sym_table.getFunc(*m_proc_name_ptr); - - // Check the types and get the code for the parameters - if (func_ptr == NULL) { - error("Unrecognized function name: '" + *m_proc_name_ptr + "'"); - } else { - int size = m_expr_vec_ptr->size(); - - Vector<Type*> f = func_ptr->getParamTypes(); - - if (size != f.size() ) { - error("Wrong number of arguments passed to function : '" + *m_proc_name_ptr + "'"); - } - else { - for(int i=0; i<size; i++) { - - // Check the types of the parameter - string param_code; - Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(param_code); - Type* expected_type_ptr = func_ptr->getParamTypes()[i]; - if (actual_type_ptr != expected_type_ptr) { - (*m_expr_vec_ptr)[i]->error("Type mismatch: expected: " + expected_type_ptr->toString() + - " actual: " + actual_type_ptr->toString()); - } - code_vec.insertAtBottom(param_code); - } - } - } - - /* OK, the semantics of "trigger" here is that, ports in the machine have - * different priorities. We always check the first port for doable - * transitions. If nothing/stalled, we pick one from the next port. - * - * One thing we have to be careful as the SLICC protocol writter is : - * If a port have two or more transitions can be picked from in one cycle, - * they must be independent. Otherwise, if transition A and B mean to be - * executed in sequential, and A get stalled, transition B can be issued - * erroneously. In practice, in most case, there is only one transition - * should be executed in one cycle for a given port. So as most of current - * protocols. - */ - - if (*m_proc_name_ptr == "trigger") { - code += indent_str() + "{\n"; - code += indent_str() + " Address addr = "; - code += code_vec[1]; - code += ";\n"; - code += indent_str() + " TransitionResult result = doTransition("; - code += code_vec[0]; - code += ", " + g_sym_table.getStateMachine()->toString() + "_getState(addr), addr"; - if(CHECK_INVALID_RESOURCE_STALLS) { - // FIXME - the current assumption is that in_buffer_rank is declared in the msg buffer peek statement - code += ", in_buffer_rank"; - } - code += ");\n"; - code += indent_str() + " if (result == TransitionResult_Valid) {\n"; - code += indent_str() + " counter++;\n"; - code += indent_str() + " continue; // Check the first port again\n"; - code += indent_str() + " }\n"; - code += indent_str() + " if (result == TransitionResult_ResourceStall) {\n"; - code += indent_str() + " g_eventQueue_ptr->scheduleEvent(this, 1);\n"; - code += indent_str() + " // Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n"; - code += indent_str() + " }\n"; - code += indent_str() + "}\n"; - } else if (*m_proc_name_ptr == "doubleTrigger") { - // NOTE: Use the doubleTrigger call with extreme caution - // the key to double trigger is the second event triggered cannot fail becuase the first event cannot be undone - assert(code_vec.size() == 4); - code += indent_str() + "{\n"; - code += indent_str() + " Address addr1 = "; - code += code_vec[1]; - code += ";\n"; - code += indent_str() + " TransitionResult result1 = doTransition("; - code += code_vec[0]; - code += ", " + g_sym_table.getStateMachine()->toString() + "_getState(addr1), addr1"; - if(CHECK_INVALID_RESOURCE_STALLS) { - // FIXME - the current assumption is that in_buffer_rank is declared in the msg buffer peek statement - code += ", in_buffer_rank"; - } - code += ");\n"; - code += indent_str() + " if (result1 == TransitionResult_Valid) {\n"; - code += indent_str() + " //this second event cannont fail because the first event already took effect\n"; - code += indent_str() + " Address addr2 = "; - code += code_vec[3]; - code += ";\n"; - code += indent_str() + " TransitionResult result2 = doTransition("; - code += code_vec[2]; - code += ", " + g_sym_table.getStateMachine()->toString() + "_getState(addr2), addr2"; - if(CHECK_INVALID_RESOURCE_STALLS) { - // FIXME - the current assumption is that in_buffer_rank is declared in the msg buffer peek statement - code += ", in_buffer_rank"; - } - code += ");\n"; - code += indent_str() + " assert(result2 == TransitionResult_Valid); // ensure the event suceeded\n"; - code += indent_str() + " counter++;\n"; - code += indent_str() + " continue; // Check the first port again\n"; - code += indent_str() + " }\n"; - code += indent_str() + " if (result1 == TransitionResult_ResourceStall) {\n"; - code += indent_str() + " g_eventQueue_ptr->scheduleEvent(this, 1);\n"; - code += indent_str() + " // Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n"; - code += indent_str() + " }\n"; - code += indent_str() + "}\n"; - } else if (*m_proc_name_ptr == "error") { - code += indent_str() + (*m_expr_vec_ptr)[0]->embedError(code_vec[0]) + "\n"; - } else if (*m_proc_name_ptr == "assert") { - code += indent_str() + "if (ASSERT_FLAG && !(" + code_vec[0] + ")) {\n"; - code += indent_str() + " " + (*m_expr_vec_ptr)[0]->embedError("\"assert failure\"") + "\n"; - code += indent_str() + "}\n"; - } else if (*m_proc_name_ptr == "continueProcessing") { - code += "counter++; continue; // Check the first port again"; - } else { - // Normal function - code += "("; - // if the func is internal to the chip but not the machine then it can only be - // accessed through the chip pointer - if (!func_ptr->existPair("external") && !func_ptr->isInternalMachineFunc()) { - code += "m_chip_ptr->"; - } - code += func_ptr->cIdent() + "("; - int size = code_vec.size(); - for(int i=0; i<size; i++) { - if (i != 0) { - code += ", "; - } - code += code_vec[i]; - } - code += "))"; - } - return func_ptr->getReturnType(); -} - -void FuncCallExprAST::print(ostream& out) const -{ - out << "[FuncCallExpr: " << *m_proc_name_ptr << " " << *m_expr_vec_ptr << "]"; -} diff --git a/src/mem/slicc/ast/FuncCallExprAST.hh b/src/mem/slicc/ast/FuncCallExprAST.hh deleted file mode 100644 index 6c02122ee..000000000 --- a/src/mem/slicc/ast/FuncCallExprAST.hh +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FuncCallExprAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef FUNCCALLEXPRAST_H -#define FUNCCALLEXPRAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - - -// ProcGen decl -class FuncGen; - -class FuncCallExprAST : public ExprAST { -public: - // Constructors - FuncCallExprAST(string* proc_name_ptr, - Vector<ExprAST*>* expr_vec_ptr); - - // Destructor - ~FuncCallExprAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const; - -private: - // Private Methods - - // Private copy constructor and assignment operator - FuncCallExprAST(const FuncCallExprAST& obj); - FuncCallExprAST& operator=(const FuncCallExprAST& obj); - - // Data Members (m_ prefix) - string* m_proc_name_ptr; - Vector<ExprAST*>* m_expr_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const FuncCallExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const FuncCallExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //FUNCCALLEXPRAST_H diff --git a/src/mem/slicc/ast/FuncCallExprAST.py b/src/mem/slicc/ast/FuncCallExprAST.py new file mode 100644 index 000000000..abf7eec7b --- /dev/null +++ b/src/mem/slicc/ast/FuncCallExprAST.py @@ -0,0 +1,168 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Func, Type + +class FuncCallExprAST(ExprAST): + def __init__(self, slicc, proc_name, exprs): + super(FuncCallExprAST, self).__init__(slicc) + self.proc_name = proc_name + self.exprs = exprs + + def __repr__(self): + return "[FuncCallExpr: %s %s]" % (self.proc_name, self.exprs) + + def generate(self, code): + machine = self.state_machine + + # DEBUG_EXPR is strange since it takes parameters of multiple types + if self.proc_name == "DEBUG_EXPR": + # FIXME - check for number of parameters + code('DEBUG_SLICC(MedPrio, "$0: ", $1)', + self.exprs[0].location, self.exprs[0].inline()) + + return self.symtab.find("void", Type) + + # hack for adding comments to profileTransition + if self.proc_name == "APPEND_TRANSITION_COMMENT": + # FIXME - check for number of parameters + code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline()) + return self.symtab.find("void", Type) + + # Look up the function in the symbol table + func = self.symtab.find(self.proc_name, Func) + + # Check the types and get the code for the parameters + if func is None: + self.error("Unrecognized function name: '%s'", self.proc_name) + + if len(self.exprs) != len(func.param_types): + self.error("Wrong number of arguments passed to function : '%s'" +\ + " Expected %d, got %d", self.proc_name, + len(func.param_types), len(self.exprs)) + + cvec = [] + for expr,expected_type in zip(self.exprs, func.param_types): + # Check the types of the parameter + actual_type,param_code = expr.inline(True) + if actual_type != expected_type: + expr.error("Type mismatch: expected: %s actual: %s" % \ + (expected_type, actual_type)) + cvec.append(param_code) + + # OK, the semantics of "trigger" here is that, ports in the + # machine have different priorities. We always check the first + # port for doable transitions. If nothing/stalled, we pick one + # from the next port. + # + # One thing we have to be careful as the SLICC protocol + # writter is : If a port have two or more transitions can be + # picked from in one cycle, they must be independent. + # Otherwise, if transition A and B mean to be executed in + # sequential, and A get stalled, transition B can be issued + # erroneously. In practice, in most case, there is only one + # transition should be executed in one cycle for a given + # port. So as most of current protocols. + + if self.proc_name == "trigger": + code(''' +{ + Address addr = ${{cvec[1]}}; + TransitionResult result = doTransition(${{cvec[0]}}, ${machine}_getState(addr), addr); + + if (result == TransitionResult_Valid) { + counter++; + continue; // Check the first port again + } + + if (result == TransitionResult_ResourceStall) { + g_eventQueue_ptr->scheduleEvent(this, 1); + + // Cannot do anything with this transition, go check next doable transition (mostly likely of next port) + } +} +''') + elif self.proc_name == "doubleTrigger": + # NOTE: Use the doubleTrigger call with extreme caution + # the key to double trigger is the second event triggered + # cannot fail becuase the first event cannot be undone + assert len(cvec) == 4 + code(''' +{ + Address addr1 = ${{cvec[1]}}; + TransitionResult result1 = + doTransition(${{cvec[0]}}, ${machine}_getState(addr1), addr1); + + if (result1 == TransitionResult_Valid) { + //this second event cannont fail because the first event + // already took effect + Address addr2 = ${{cvec[3]}}; + TransitionResult result2 = doTransition(${{cvec[2]}}, ${machine}_getState(addr2), addr2); + + // ensure the event suceeded + assert(result2 == TransitionResult_Valid); + + counter++; + continue; // Check the first port again + } + + if (result1 == TransitionResult_ResourceStall) { + g_eventQueue_ptr->scheduleEvent(this, 1); + // Cannot do anything with this transition, go check next + // doable transition (mostly likely of next port) + } +} +''') + elif self.proc_name == "error": + code("$0", self.exprs[0].embedError(cvec[0])) + elif self.proc_name == "assert": + error = self.exprs[0].embedError('"assert failure"') + code(''' +if (ASSERT_FLAG && !(${{cvec[0]}})) { + $error +} +''') + + elif self.proc_name == "continueProcessing": + code("counter++;") + code("continue; // Check the first port again") + else: + # Normal function + + # if the func is internal to the chip but not the machine + # then it can only be accessed through the chip pointer + internal = "" + if "external" not in func and not func.isInternalMachineFunc: + internal = "m_chip_ptr->" + + params = ', '.join(str(c) for c in cvec) + fix = code.nofix() + code('(${internal}${{func.c_ident}}($params))') + code.fix(fix) + + return func.return_type diff --git a/src/mem/slicc/ast/FuncDeclAST.cc b/src/mem/slicc/ast/FuncDeclAST.cc deleted file mode 100644 index 2a0905f06..000000000 --- a/src/mem/slicc/ast/FuncDeclAST.cc +++ /dev/null @@ -1,112 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FuncDeclAST.C - * - * Description: See FuncDeclAST.hh - * - * $Id: FuncDeclAST.C,v 3.4 2003/08/22 18:19:34 beckmann Exp $ - * - */ - -#include "mem/slicc/ast/FuncDeclAST.hh" -#include "mem/slicc/ast/FormalParamAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/main.hh" - -FuncDeclAST::FuncDeclAST(TypeAST* return_type_ast_ptr, - string* ident_ptr, - Vector<FormalParamAST*>* formal_vec_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr) - : DeclAST(pairs_ptr) -{ - m_return_type_ast_ptr = return_type_ast_ptr; - m_ident_ptr = ident_ptr; - m_formal_vec_ptr = formal_vec_ptr; - m_statement_list_ptr = statement_list_ptr; -} - -FuncDeclAST::~FuncDeclAST() -{ - delete m_return_type_ast_ptr; - delete m_ident_ptr; - - int size = m_formal_vec_ptr->size(); - for(int i=0; i<size; i++) { - delete (*m_formal_vec_ptr)[i]; - } - delete m_formal_vec_ptr; - delete m_statement_list_ptr; -} - -void FuncDeclAST::generate() -{ - Vector<Type*> type_vec; - Vector<string> param_vec; - Type* void_type_ptr = g_sym_table.getType("void"); - - // Generate definition code - g_sym_table.pushFrame(); - - // Lookup return type - Type* return_type_ptr = m_return_type_ast_ptr->lookupType(); - - // Generate function header - int size = m_formal_vec_ptr->size(); - for(int i=0; i<size; i++) { - // Lookup parameter types - string ident; - Type* type_ptr = (*m_formal_vec_ptr)[i]->generate(ident); - type_vec.insertAtBottom(type_ptr); - param_vec.insertAtBottom(ident); - } - - string body; - if (m_statement_list_ptr == NULL) { - getPairs().add("external", "yes"); - } else { - m_statement_list_ptr->generate(body, return_type_ptr); - } - g_sym_table.popFrame(); - - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr != NULL) { - machine_ptr->addFunc(new Func(*m_ident_ptr, getLocation(), return_type_ptr, type_vec, param_vec, body, getPairs(), machine_ptr)); - } else { - g_sym_table.newSym(new Func(*m_ident_ptr, getLocation(), return_type_ptr, type_vec, param_vec, body, getPairs(), machine_ptr)); - } - -} - -void FuncDeclAST::print(ostream& out) const -{ - out << "[FuncDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/FuncDeclAST.hh b/src/mem/slicc/ast/FuncDeclAST.hh deleted file mode 100644 index 205e71a85..000000000 --- a/src/mem/slicc/ast/FuncDeclAST.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FuncDeclAST.hh - * - * Description: - * - * $Id: FuncDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef FuncDeclAST_H -#define FuncDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class FormalParamsAST; - -class FuncDeclAST : public DeclAST { -public: - // Constructors - FuncDeclAST(TypeAST* return_type_ptr, - string* ident_ptr, - Vector<FormalParamAST*>* formal_vec_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr); - // Destructor - ~FuncDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - FuncDeclAST(const FuncDeclAST& obj); - FuncDeclAST& operator=(const FuncDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_return_type_ast_ptr; - Vector<FormalParamAST*>* m_formal_vec_ptr; - StatementListAST* m_statement_list_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const FuncDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const FuncDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //FuncDeclAST_H diff --git a/src/mem/slicc/ast/FuncDeclAST.py b/src/mem/slicc/ast/FuncDeclAST.py new file mode 100644 index 000000000..980804c2a --- /dev/null +++ b/src/mem/slicc/ast/FuncDeclAST.py @@ -0,0 +1,88 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util.code_formatter import code_formatter + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Func, Type + +class FuncDeclAST(DeclAST): + def __init__(self, slicc, return_type, ident, formals, pairs, statements): + super(FuncDeclAST, self).__init__(slicc, pairs) + + self.return_type = return_type + self.ident = ident + self.formals = formals + self.statements = statements + + def __repr__(self): + return "[FuncDecl: %s]" % self.ident + + def files(self, parent=None): + if "external" in self or self.statements is None: + return set() + + if parent: + ident = "%s_%s" % (parent, self.ident) + else: + ident = self.ident + return set(("%s.cc" % ident,)) + + def generate(self): + types = [] + params = [] + void_type = self.symtab.find("void", Type) + + # Generate definition code + self.symtab.pushFrame() + + # Lookup return type + return_type = self.return_type.type + + # Generate function header + for formal in self.formals: + # Lookup parameter types + type, ident = formal.generate() + types.append(type) + params.append(ident) + + body = code_formatter() + if self.statements is None: + self["external"] = "yes" + else: + rtype = self.statements.generate(body, return_type) + + self.symtab.popFrame() + + machine = self.state_machine + func = Func(self.symtab, self.ident, self.location, return_type, + types, params, str(body), self.pairs, machine) + + if machine is not None: + machine.addFunc(func) + else: + self.symtab.newSymbol(func) diff --git a/src/mem/slicc/ast/IfStatementAST.cc b/src/mem/slicc/ast/IfStatementAST.cc deleted file mode 100644 index 40942a58d..000000000 --- a/src/mem/slicc/ast/IfStatementAST.cc +++ /dev/null @@ -1,98 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * IfStatementAST.C - * - * Description: See IfStatementAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/IfStatementAST.hh" - -IfStatementAST::IfStatementAST(ExprAST* cond_ptr, - StatementListAST* then_ptr, - StatementListAST* else_ptr) - : StatementAST() -{ - assert(cond_ptr != NULL); - assert(then_ptr != NULL); - m_cond_ptr = cond_ptr; - m_then_ptr = then_ptr; - m_else_ptr = else_ptr; -} - -IfStatementAST::~IfStatementAST() -{ - delete m_cond_ptr; - delete m_then_ptr; - delete m_else_ptr; -} - - -void IfStatementAST::generate(string& code, Type* return_type_ptr) const -{ - Type* type_ptr; - - // Conditional - code += indent_str() + "if ("; - type_ptr = m_cond_ptr->generate(code); - if (type_ptr != g_sym_table.getType("bool")) { - m_cond_ptr->error("Condition of if statement must be boolean, type was '" + type_ptr->toString() + "'"); - } - code += ") {\n"; - // Then part - inc_indent(); - m_then_ptr->generate(code, return_type_ptr); - dec_indent(); - // Else part - if (m_else_ptr != NULL) { - code += indent_str() + "} else {\n"; - inc_indent(); - m_else_ptr->generate(code, return_type_ptr); - dec_indent(); - } - code += indent_str() + "}\n"; // End scope -} - -void IfStatementAST::findResources(Map<Var*, string>& resource_list) const -{ - // Take a worse case look at both paths - m_then_ptr->findResources(resource_list); - if (m_else_ptr != NULL) { - m_else_ptr->findResources(resource_list); - } -} - -void IfStatementAST::print(ostream& out) const -{ - out << "[IfStatement: " << *m_cond_ptr << *m_then_ptr << *m_else_ptr << "]"; -} diff --git a/src/mem/slicc/ast/IfStatementAST.hh b/src/mem/slicc/ast/IfStatementAST.hh deleted file mode 100644 index 2c168913a..000000000 --- a/src/mem/slicc/ast/IfStatementAST.hh +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * IfStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef IFSTATEMENTAST_H -#define IFSTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" - - -class IfStatementAST : public StatementAST { -public: - // Constructors - IfStatementAST(ExprAST* cond_ptr, - StatementListAST* then_ptr, - StatementListAST* else_ptr); - - // Destructor - ~IfStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - IfStatementAST(const IfStatementAST& obj); - IfStatementAST& operator=(const IfStatementAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_cond_ptr; - StatementListAST* m_then_ptr; - StatementListAST* m_else_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const IfStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const IfStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //IFSTATEMENTAST_H diff --git a/src/mem/slicc/ast/IfStatementAST.py b/src/mem/slicc/ast/IfStatementAST.py new file mode 100644 index 000000000..788876fd1 --- /dev/null +++ b/src/mem/slicc/ast/IfStatementAST.py @@ -0,0 +1,74 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.StatementAST import StatementAST +from slicc.symbols import Type + +class IfStatementAST(StatementAST): + def __init__(self, slicc, cond, then, else_): + super(IfStatementAST, self).__init__(slicc) + + assert cond is not None + assert then is not None + + self.cond = cond + self.then = then + self.else_ = else_ + + def __repr__(self): + return "[IfStatement: %r%r%r]" % (self.cond, self.then, self.else_) + + def generate(self, code, return_type): + cond_code = code_formatter() + cond_type = self.cond.generate(cond_code) + + if cond_type != self.symtab.find("bool", Type): + self.cond.error("Condition of if stmt must be bool, type was '%s'", + ctype) + + # Conditional + code.indent() + code('if ($cond_code) {') + # Then part + code.indent() + self.then.generate(code, return_type) + code.dedent() + # Else part + if self.else_: + code('} else {') + code.indent() + self.else_.generate(code, return_type) + code.dedent() + code('}') # End scope + + def findResources(self, resources): + # Take a worse case look at both paths + self.then.findResources(resources) + if self.else_ is not None: + self.else_.findResources(resources) diff --git a/src/mem/slicc/ast/InPortDeclAST.cc b/src/mem/slicc/ast/InPortDeclAST.cc deleted file mode 100644 index f62af9921..000000000 --- a/src/mem/slicc/ast/InPortDeclAST.cc +++ /dev/null @@ -1,149 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InPortDeclAST.C - * - * Description: See InPortDeclAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/InPortDeclAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/symbols/Var.hh" - -InPortDeclAST::InPortDeclAST(string* ident_ptr, - TypeAST* msg_type_ptr, - ExprAST* var_expr_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr) - : DeclAST(pairs_ptr) -{ - m_ident_ptr = ident_ptr; - m_msg_type_ptr = msg_type_ptr; - m_var_expr_ptr = var_expr_ptr; - m_statement_list_ptr = statement_list_ptr; - m_queue_type_ptr = new TypeAST(new string("InPort")); -} - -InPortDeclAST::~InPortDeclAST() -{ - delete m_ident_ptr; - delete m_msg_type_ptr; - delete m_var_expr_ptr; - delete m_statement_list_ptr; - delete m_queue_type_ptr; -} - -void InPortDeclAST::generate() -{ - string code; - Type* queue_type_ptr = m_var_expr_ptr->generate(code); - if (!queue_type_ptr->isInPort()) { - error("Inport queues must be of a type that has the 'inport' attribute. The type '" + - queue_type_ptr->toString() + "' does not have this attribute."); - } - - Type* type_ptr = m_queue_type_ptr->lookupType(); - Var* in_port_ptr = new Var(*m_ident_ptr, getLocation(), type_ptr, code, getPairs()); - g_sym_table.newSym(in_port_ptr); - - g_sym_table.pushFrame(); - Vector<Type*> param_type_vec; - - // Check for Event - type_ptr = g_sym_table.getType("Event"); - if (type_ptr == NULL) { - error("in_port declarations require 'Event' enumeration to be defined"); - } - param_type_vec.insertAtBottom(type_ptr); - - // Check for Address - type_ptr = g_sym_table.getType("Address"); - if (type_ptr == NULL) { - error("in_port declarations require 'Address' type to be defined"); - } - param_type_vec.insertAtBottom(type_ptr); - - // Add the trigger method - FIXME, this is a bit dirty - Map<string, string> pairs; - pairs.add("external", "yes"); - Vector<string> string_vec; - g_sym_table.newSym(new Func("trigger", getLocation(), g_sym_table.getType("void"), param_type_vec, string_vec, string(""), pairs, NULL)); - - // Check for Event2 - type_ptr = g_sym_table.getType("Event"); - if (type_ptr == NULL) { - error("in_port declarations require 'Event' enumeration to be defined"); - } - param_type_vec.insertAtBottom(type_ptr); - - // Check for Address2 - type_ptr = g_sym_table.getType("Address"); - if (type_ptr == NULL) { - error("in_port declarations require 'Address' type to be defined"); - } - param_type_vec.insertAtBottom(type_ptr); - - // Add the doubleTrigger method - this hack supports tiggering two simulateous events - // The key is that the second transistion cannot fail because the first event cannot be undone - // therefore you must do some checks before calling double trigger to ensure that won't happen - g_sym_table.newSym(new Func("doubleTrigger", getLocation(), g_sym_table.getType("void"), param_type_vec, string_vec, string(""), pairs, NULL)); - - // Add the continueProcessing method - this hack supports messages that don't trigger events - Vector<Type*> empty_param_type_vec; - Vector<string> empty_string_vec; - g_sym_table.newSym(new Func("continueProcessing", getLocation(), g_sym_table.getType("void"), empty_param_type_vec, empty_string_vec, string(""), pairs, NULL)); - - if (m_statement_list_ptr != NULL) { - inc_indent(); - inc_indent(); - string code; - m_statement_list_ptr->generate(code, NULL); - in_port_ptr->addPair("c_code_in_port", code); - dec_indent(); - dec_indent(); - } - g_sym_table.popFrame(); - - // Add port to state machine - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr == NULL) { - error("InPort declaration not part of a machine."); - } - machine_ptr->addInPort(in_port_ptr); -} - - -void InPortDeclAST::print(ostream& out) const -{ - out << "[InPortDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/InPortDeclAST.hh b/src/mem/slicc/ast/InPortDeclAST.hh deleted file mode 100644 index e6295a6e2..000000000 --- a/src/mem/slicc/ast/InPortDeclAST.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InPortDeclAST.hh - * - * Description: - * - * $Id: InPortDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef InPortDeclAST_H -#define InPortDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" - -class InPortDeclAST : public DeclAST { -public: - // Constructors - InPortDeclAST(string* ident_ptr, - TypeAST* msg_type_ptr, - ExprAST* var_expr_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr); - - // Destructor - ~InPortDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - InPortDeclAST(const InPortDeclAST& obj); - InPortDeclAST& operator=(const InPortDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_msg_type_ptr; - ExprAST* m_var_expr_ptr; - StatementListAST* m_statement_list_ptr; - TypeAST* m_queue_type_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const InPortDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const InPortDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //InPortDeclAST_H diff --git a/src/mem/slicc/ast/InPortDeclAST.py b/src/mem/slicc/ast/InPortDeclAST.py new file mode 100644 index 000000000..3dde24557 --- /dev/null +++ b/src/mem/slicc/ast/InPortDeclAST.py @@ -0,0 +1,130 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.DeclAST import DeclAST +from slicc.ast.TypeAST import TypeAST +from slicc.symbols import Func, Type, Var + +class InPortDeclAST(DeclAST): + def __init__(self, slicc, ident, msg_type, var_expr, pairs, statements): + super(InPortDeclAST, self).__init__(slicc, pairs) + + self.ident = ident + self.msg_type = msg_type + self.var_expr = var_expr + self.statements = statements + self.queue_type = TypeAST(slicc, "InPort") + + def __repr__(self): + return "[InPortDecl: %s]" % self.ident + + def generate(self): + symtab = self.symtab + void_type = symtab.find("void", Type) + + code = code_formatter() + queue_type = self.var_expr.generate(code) + if not queue_type.isInPort: + self.error("The inport queue's type must have the 'inport' " + \ + "attribute. Type '%s' does not have this attribute.", + queue_type) + + type = self.queue_type.type + in_port = Var(self.symtab, self.ident, self.location, type, str(code), + self.pairs) + symtab.newSymbol(in_port) + + symtab.pushFrame() + param_types = [] + + # Check for Event + type = symtab.find("Event", Type) + if type is None: + self.error("in_port decls require 'Event' enumeration defined") + param_types.append(type) + + # Check for Address + type = symtab.find("Address", Type) + if type is None: + self.error("in_port decls require 'Address' type to be defined") + + param_types.append(type) + + # Add the trigger method - FIXME, this is a bit dirty + pairs = { "external" : "yes" } + func = Func(self.symtab, "trigger", self.location, void_type, + param_types, [], "", pairs, None) + symtab.newSymbol(func) + + param_types = [] + # Check for Event2 + type = symtab.find("Event", Type) + if type is None: + self.error("in_port decls require 'Event' enumeration") + + param_types.append(type) + + # Check for Address2 + type = symtab.find("Address", Type) + if type is None: + self.error("in_port decls require 'Address' type to be defined") + + param_types.append(type) + + # Add the doubleTrigger method - this hack supports tiggering + # two simulateous events + # + # The key is that the second transistion cannot fail because + # the first event cannot be undone therefore you must do some + # checks before calling double trigger to ensure that won't + # happen + func = Func(self.symtab, "doubleTrigger", self.location, void_type, + param_types, [], "", pairs, None) + symtab.newSymbol(func) + + # Add the continueProcessing method - this hack supports + # messages that don't trigger events + func = Func(self.symtab, "continueProcessing", self.location, + void_type, [], [], "", pairs, None) + symtab.newSymbol(func) + + if self.statements is not None: + rcode = code_formatter() + rcode.indent() + rcode.indent() + self.statements.generate(rcode, None) + in_port["c_code_in_port"] = str(rcode) + symtab.popFrame() + + # Add port to state machine + machine = symtab.state_machine + if machine is None: + self.error("InPort declaration not part of a machine.") + + machine.addInPort(in_port) diff --git a/src/mem/slicc/ast/InfixOperatorExprAST.cc b/src/mem/slicc/ast/InfixOperatorExprAST.cc deleted file mode 100644 index 40719fc66..000000000 --- a/src/mem/slicc/ast/InfixOperatorExprAST.cc +++ /dev/null @@ -1,121 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InfixOperatorExprAST.C - * - * Description: See InfixOperatorExprAST.hh - * - * $Id: InfixOperatorExprAST.C,v 3.2 2004/01/31 20:46:15 milo Exp $ - * - */ - -#include "mem/slicc/ast/InfixOperatorExprAST.hh" - -InfixOperatorExprAST::InfixOperatorExprAST(ExprAST* left_ptr, - string* op_ptr, - ExprAST* right_ptr) - : ExprAST() -{ - m_left_ptr = left_ptr; - m_op_ptr = op_ptr; - m_right_ptr = right_ptr; -} - -InfixOperatorExprAST::~InfixOperatorExprAST() -{ - delete m_left_ptr; - delete m_op_ptr; - delete m_right_ptr; -} - -Type* InfixOperatorExprAST::generate(string& code) const -{ - code += "("; - Type* left_type_ptr = m_left_ptr->generate(code); - code += " " + *m_op_ptr + " "; - Type* right_type_ptr = m_right_ptr->generate(code); - code += ")"; - - string inputs, output; - // Figure out what the input and output types should be - if ((*m_op_ptr == "==" || - *m_op_ptr == "!=")) { - output = "bool"; - if (left_type_ptr != right_type_ptr) { - error("Type mismatch: left & right operand of operator '" + *m_op_ptr + - "' must be the same type." + - "left: '" + left_type_ptr->toString() + - "', right: '" + right_type_ptr->toString() + "'"); - } - } else { - if ((*m_op_ptr == "&&" || - *m_op_ptr == "||")) { - // boolean inputs and output - inputs = "bool"; - output = "bool"; - } else if ((*m_op_ptr == "==" || - *m_op_ptr == "!=" || - *m_op_ptr == ">=" || - *m_op_ptr == "<=" || - *m_op_ptr == ">" || - *m_op_ptr == "<")) { - // Integer inputs, boolean output - inputs = "int"; - output = "bool"; - } else { - // integer inputs and output - inputs = "int"; - output = "int"; - } - - Type* inputs_type = g_sym_table.getType(inputs); - - if (inputs_type != left_type_ptr) { - m_left_ptr->error("Type mismatch: left operand of operator '" + *m_op_ptr + - "' expects input type '" + inputs + "', actual was " + left_type_ptr->toString() + "'"); - } - - if (inputs_type != right_type_ptr) { - m_right_ptr->error("Type mismatch: right operand of operator '" + *m_op_ptr + - "' expects input type '" + inputs + "', actual was '" + right_type_ptr->toString() + "'"); - } - } - - // All is well - Type* output_type = g_sym_table.getType(output); - return output_type; -} - - -void InfixOperatorExprAST::print(ostream& out) const -{ - out << "[InfixExpr: " << *m_left_ptr - << *m_op_ptr << *m_right_ptr << "]"; -} diff --git a/src/mem/slicc/ast/InfixOperatorExprAST.py b/src/mem/slicc/ast/InfixOperatorExprAST.py new file mode 100644 index 000000000..c4fb4a4db --- /dev/null +++ b/src/mem/slicc/ast/InfixOperatorExprAST.py @@ -0,0 +1,89 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Type + +class InfixOperatorExprAST(ExprAST): + def __init__(self, slicc, left, op, right): + super(InfixOperatorExprAST, self).__init__(slicc) + + self.left = left + self.op = op + self.right = right + + def __repr__(self): + return "[InfixExpr: %r %s %r]" % (self.left, self.op, self.right) + + def generate(self, code): + lcode = code_formatter() + rcode = code_formatter() + + ltype = self.left.generate(lcode) + rtype = self.right.generate(rcode) + + # Figure out what the input and output types should be + if self.op in ("==", "!="): + output = "bool" + if (ltype != rtype): + self.error("Type mismatch: left and right operands of " + + "operator '%s' must be the same type. " + + "left: '%s', right: '%s'", + self.op, ltype, rtype) + else: + if self.op in ("&&", "||"): + # boolean inputs and output + inputs = "bool" + output = "bool" + elif self.op in ("==", "!=", ">=", "<=", ">", "<"): + # Integer inputs, boolean output + inputs = "int" + output = "bool" + else: + # integer inputs and output + inputs = "int" + output = "int" + + inputs_type = self.symtab.find(inputs, Type) + + if inputs_type != ltype: + self.left.error("Type mismatch: left operand of operator " + + "'%s' expects type '%s', actual was '%s'", + self.op, inputs, ltype) + + if inputs_type != rtype: + self.right.error("Type mismatch: right operand of operator " + + "'%s' expects type '%s', actual was '%s'", + self.op, inputs, rtype) + + # All is well + fix = code.nofix() + code("($lcode ${{self.op}} $rcode)") + code.fix(fix) + return self.symtab.find(output, Type) diff --git a/src/mem/slicc/ast/LiteralExprAST.py b/src/mem/slicc/ast/LiteralExprAST.py new file mode 100644 index 000000000..773e8f35c --- /dev/null +++ b/src/mem/slicc/ast/LiteralExprAST.py @@ -0,0 +1,55 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Type + +class LiteralExprAST(ExprAST): + def __init__(self, slicc, literal, type): + super(LiteralExprAST, self).__init__(slicc) + self.literal = literal + self.type = type + + def __repr__(self): + return "[Literal: %s]" % self.literal + + def generate(self, code): + fix = code.nofix() + if self.type == "string": + code('("${{self.literal}}")') + elif self.type == "bool": + code('(${{str(self.literal).lower()}})') + else: + code('(${{self.literal}})') + code.fix(fix) + + type = self.symtab.find(self.type, Type) + if type is None: + # Can't find the type + self.error("Internal: can't primitive type '%s'" % self.type) + + return type diff --git a/src/mem/slicc/ast/Location.cc b/src/mem/slicc/ast/Location.cc deleted file mode 100644 index fd224fe2f..000000000 --- a/src/mem/slicc/ast/Location.cc +++ /dev/null @@ -1,87 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Location.C - * - * Description: See Location.hh - * - * $Id: Location.C,v 3.3 2004/05/30 22:19:02 kmoore Exp $ - * - */ - -#include "mem/slicc/ast/Location.hh" - -int g_line_number = 0; -string &g_file_name() -{ - static string the_string; - return the_string; -} - -Location::Location() -{ - m_file_name = g_file_name(); - m_line_number = g_line_number; - - ostringstream sstr; - sstr << getLineNumber(); - m_line_number_str = sstr.str(); -} - -void Location::error(string err_msg) const -{ - cerr << endl; - cerr << toString() << ": Error: " << err_msg << endl; - exit(1); -} - -string Location::embedError(string err_msg) const -{ - string code; - code += "cerr << \"Runtime Error at "; - code += toString() + ", Ruby Time: \" << "; - code += "g_eventQueue_ptr->getTime() << \": \" << "; - code += err_msg; - code += " << \", PID: \" << getpid() << endl;\n"; - code += "char c; cerr << \"press return to continue.\" << endl; cin.get(c); abort();\n"; - - return code; -} - -void Location::warning(string err_msg) const -{ - cerr << toString() << ": Warning: " - << err_msg << endl; -} - -string Location::toString() const -{ - return m_file_name + ":" + m_line_number_str; -} diff --git a/src/mem/slicc/ast/Location.hh b/src/mem/slicc/ast/Location.hh deleted file mode 100644 index c9e20418e..000000000 --- a/src/mem/slicc/ast/Location.hh +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Location.hh - * - * Description: - * - * $Id: Location.hh,v 3.1 2001/12/12 01:00:20 milo Exp $ - * - */ - -#ifndef LOCATION_H -#define LOCATION_H - -#include "mem/slicc/slicc_global.hh" - -extern int g_line_number; -extern string &g_file_name(); - -class Location { -public: - // Constructors - Location(); - - // Destructor - //~Location(); - - // Public Methods - - void print(ostream& out) const; - void error(string err_msg) const; - string embedError(string err_msg) const; - void warning(string err_msg) const; - string toString() const; - -private: - // Private Methods - const string& getFileName() const { return m_file_name; } - int getLineNumber() const { return m_line_number; } - string getLineNumberStr() const { return m_line_number_str; } - - // Private copy constructor and assignment operator - //Location(const Location& obj); - //Location& operator=(const Location& obj); - - // Data Members (m_ prefix) - string m_file_name; - int m_line_number; - string m_line_number_str; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Location& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Location& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //LOCATION_H diff --git a/src/mem/slicc/ast/MachineAST.cc b/src/mem/slicc/ast/MachineAST.cc deleted file mode 100644 index ae8026458..000000000 --- a/src/mem/slicc/ast/MachineAST.cc +++ /dev/null @@ -1,99 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * MachineAST.cc - * - * Description: See MachineAST.hh - * - * $Id: MachineAST.cc,v 3.1 2003/03/17 01:54:25 xu Exp $ - * - */ - -#include "mem/slicc/ast/MachineAST.hh" -#include "mem/slicc/ast/FormalParamAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -MachineAST::MachineAST(string* ident_ptr, - PairListAST* pairs_ptr, - Vector<FormalParamAST*>* config_parameters, - DeclListAST* decl_list_ptr) - - : DeclAST(pairs_ptr) -{ - m_ident_ptr = ident_ptr; - m_pairs_ptr = pairs_ptr; - m_config_parameters = config_parameters; - m_decl_list_ptr = decl_list_ptr; -} - -MachineAST::~MachineAST() -{ - delete m_ident_ptr; - delete m_pairs_ptr; - delete m_decl_list_ptr; -} - -void MachineAST::generate() -{ - StateMachine* machine_ptr; - - // Make a new frame - g_sym_table.pushFrame(); - - // Create a new machine - machine_ptr = new StateMachine(*m_ident_ptr, getLocation(), getPairs(), m_config_parameters); - g_sym_table.newCurrentMachine(machine_ptr); - - // Generate code for all the internal decls - m_decl_list_ptr->generate(); - - // Build the transition table - machine_ptr->buildTable(); - - // Pop the frame - g_sym_table.popFrame(); -} - -void MachineAST::findMachines() -{ - // Add to MachineType enumeration - Type* type_ptr = g_sym_table.getType("MachineType"); - if (!type_ptr->enumAdd(*m_ident_ptr, m_pairs_ptr->getPairs())) { - error("Duplicate machine name: " + type_ptr->toString() + ":" + *m_ident_ptr); - } - - // Generate code for all the internal decls - m_decl_list_ptr->findMachines(); -} - -void MachineAST::print(ostream& out) const -{ - out << "[Machine: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/MachineAST.hh b/src/mem/slicc/ast/MachineAST.hh deleted file mode 100644 index 5d1bc2a1c..000000000 --- a/src/mem/slicc/ast/MachineAST.hh +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ActionDeclAST.hh - * - * Description: - * - * $Id: MachineAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef MachineAST_H -#define MachineAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/DeclListAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -class FormalParamAST; - -class MachineAST : public DeclAST { -public: - // Constructors - MachineAST(string* ident_ptr, - PairListAST* pairs_ptr, - Vector<FormalParamAST*>* config_parameters, - DeclListAST* decl_list_ptr); - - // Destructor - ~MachineAST(); - - // Public Methods - void print(ostream& out) const; - void generate(); - void findMachines(); -private: - // Private Methods - - // Private copy constructor and assignment operator - MachineAST(const MachineAST& obj); - MachineAST& operator=(const MachineAST& obj); - - // Data Members (m_ prefix) - Vector<FormalParamAST*>* m_config_parameters; - string* m_ident_ptr; - DeclListAST* m_decl_list_ptr; - PairListAST* m_pairs_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const MachineAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const MachineAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //MachineAST_H diff --git a/src/mem/slicc/ast/MachineAST.py b/src/mem/slicc/ast/MachineAST.py new file mode 100644 index 000000000..ee75b6d6a --- /dev/null +++ b/src/mem/slicc/ast/MachineAST.py @@ -0,0 +1,81 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import StateMachine, Type + +class MachineAST(DeclAST): + def __init__(self, slicc, ident, pairs_ast, config_parameters, decls): + super(MachineAST, self).__init__(slicc, pairs_ast) + + self.ident = ident + self.pairs_ast = pairs_ast + self.config_parameters = config_parameters + self.decls = decls + + def __repr__(self): + return "[Machine: %r]" % self.ident + + def files(self, parent=None): + s = set(('%s_Controller.cc' % self.ident, + '%s_Controller.hh' % self.ident, + '%s_Profiler.cc' % self.ident, + '%s_Profiler.hh' % self.ident, + '%s_Transitions.cc' % self.ident, + '%s_Wakeup.cc' % self.ident)) + + s |= self.decls.files(self.ident) + return s + + def generate(self): + # Make a new frame + self.symtab.pushFrame() + + # Create a new machine + machine = StateMachine(self.symtab, self.ident, self.location, + self.pairs, self.config_parameters) + + self.symtab.newCurrentMachine(machine) + + # Generate code for all the internal decls + self.decls.generate() + + # Build the transition table + machine.buildTable() + + # Pop the frame + self.symtab.popFrame() + + def findMachines(self): + # Add to MachineType enumeration + machine_type = self.symtab.find("MachineType", Type) + if not machine_type.enumAdd(self.ident, self.pairs_ast.pairs): + self.error("Duplicate machine name: %s:%s" % (machine_type, + self.ident)) + + # Generate code for all the internal decls + self.decls.findMachines() diff --git a/src/mem/slicc/ast/MemberExprAST.cc b/src/mem/slicc/ast/MemberExprAST.cc deleted file mode 100644 index 1bcfdc7f1..000000000 --- a/src/mem/slicc/ast/MemberExprAST.cc +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FieldExprAST.C - * - * Description: See FieldExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/MemberExprAST.hh" - -MemberExprAST::MemberExprAST(ExprAST* expr_ast_ptr, string* field_ptr) - : ExprAST() -{ - m_expr_ast_ptr = expr_ast_ptr; - m_field_ptr = field_ptr; -} - -MemberExprAST::~MemberExprAST() -{ - delete m_expr_ast_ptr; - delete m_field_ptr; -} - -Type* MemberExprAST::generate(string& code) const -{ - code += "("; - Type* type_ptr = m_expr_ast_ptr->generate(code); - code += ").m_" + (*m_field_ptr); - - // Verify that this is a valid field name for this type - if (!type_ptr->dataMemberExist(*m_field_ptr)) { - error("Invalid object field: Type '" + type_ptr->toString() + "' does not have data member " + *m_field_ptr); - } - - // Return the type of the field - return type_ptr->dataMemberType(*m_field_ptr); -} - -void MemberExprAST::print(ostream& out) const -{ - out << "[MemberExprAST: " << *m_expr_ast_ptr << "." << *m_field_ptr << "]"; -} diff --git a/src/mem/slicc/ast/MemberExprAST.hh b/src/mem/slicc/ast/MemberExprAST.hh deleted file mode 100644 index 34b694882..000000000 --- a/src/mem/slicc/ast/MemberExprAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * MemberExprAST.hh - * - * Description: - * - * $Id: MemberExprAST.hh,v 3.1 2001/12/12 01:00:21 milo Exp $ - * - */ - -#ifndef MemberExprAST_H -#define MemberExprAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" - - -class MemberExprAST : public ExprAST { -public: - // Constructors - MemberExprAST(ExprAST* expr_ast_ptr, string* field_ptr); - - // Destructor - ~MemberExprAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - MemberExprAST(const MemberExprAST& obj); - MemberExprAST& operator=(const MemberExprAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_expr_ast_ptr; - string* m_field_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const MemberExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const MemberExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //MemberExprAST_H diff --git a/src/mem/slicc/ast/MemberExprAST.py b/src/mem/slicc/ast/MemberExprAST.py new file mode 100644 index 000000000..c62e28741 --- /dev/null +++ b/src/mem/slicc/ast/MemberExprAST.py @@ -0,0 +1,55 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.ExprAST import ExprAST + +class MemberExprAST(ExprAST): + def __init__(self, slicc, expr_ast, field): + super(MemberExprAST, self).__init__(slicc) + + self.expr_ast = expr_ast + self.field = field + + def __repr__(self): + return "[MemberExprAST: %r.%r]" % (self.expr_ast, self.field) + + def generate(self, code): + return_type, gcode = self.expr_ast.inline(True) + fix = code.nofix() + code("($gcode).m_${{self.field}}") + code.fix(fix) + + # Verify that this is a valid field name for this type + if self.field not in return_type.data_members: + self.error("Invalid object field: " + + "Type '%s' does not have data member %s" % \ + (return_type, self.field)) + + # Return the type of the field + return return_type.data_members[self.field].type diff --git a/src/mem/slicc/ast/MethodCallExprAST.cc b/src/mem/slicc/ast/MethodCallExprAST.cc deleted file mode 100644 index 1bfe312ff..000000000 --- a/src/mem/slicc/ast/MethodCallExprAST.cc +++ /dev/null @@ -1,160 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * MethodCallExprAST.cc - * - * Description: See MethodCallExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/MethodCallExprAST.hh" - -MethodCallExprAST::MethodCallExprAST(ExprAST* obj_expr_ptr, - string* proc_name_ptr, - Vector<ExprAST*>* expr_vec_ptr) - : ExprAST() -{ - m_obj_expr_ptr = obj_expr_ptr; - m_type_ptr = NULL; - m_proc_name_ptr = proc_name_ptr; - m_expr_vec_ptr = expr_vec_ptr; -} - -MethodCallExprAST::MethodCallExprAST(TypeAST* type_ptr, - string* proc_name_ptr, - Vector<ExprAST*>* expr_vec_ptr) - : ExprAST() -{ - m_obj_expr_ptr = NULL; - m_type_ptr = type_ptr; - m_proc_name_ptr = proc_name_ptr; - m_expr_vec_ptr = expr_vec_ptr; -} - -MethodCallExprAST::~MethodCallExprAST() -{ - delete m_obj_expr_ptr; - delete m_type_ptr; - delete m_proc_name_ptr; - int size = m_expr_vec_ptr->size(); - for(int i=0; i<size; i++) { - delete (*m_expr_vec_ptr)[i]; - } - delete m_expr_vec_ptr; -} - -Type* MethodCallExprAST::generate(string& code) const -{ - Type* obj_type_ptr = NULL; - - string methodId; - Vector <Type*> paramTypes; - - int actual_size = m_expr_vec_ptr->size(); - for(int i=0; i<actual_size; i++) { - string tmp; - Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(tmp); - paramTypes.insertAtBottom(actual_type_ptr); - } - - if(m_obj_expr_ptr) { - // member method call - string tmp; - obj_type_ptr = m_obj_expr_ptr->generate(tmp); - methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes); - if (obj_type_ptr->methodReturnType(methodId)->isInterface()) - code += "static_cast<" + obj_type_ptr->methodReturnType(methodId)->cIdent() + "&>"; - code += "(("; - code += tmp; - code += ")."; - } else if (m_type_ptr) { - // class method call - code += "(" + m_type_ptr->toString() + "::"; - obj_type_ptr = m_type_ptr->lookupType(); - methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes); - } else { - // impossible - assert(0); - } - - // generate code - actual_size = m_expr_vec_ptr->size(); - code += (*m_proc_name_ptr) + "("; - for(int i=0; i<actual_size; i++) { - if (i != 0) { - code += ", "; - } - // Check the types of the parameter - Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(code); - } - code += "))"; - - // Verify that this is a method of the object - if (!obj_type_ptr->methodExist(methodId)) { - error("Invalid method call: Type '" + obj_type_ptr->toString() + "' does not have a method '" + methodId + "'"); - } - - int expected_size = obj_type_ptr->methodParamType(methodId).size(); - if (actual_size != expected_size) { - // Right number of parameters - ostringstream err; - err << "Wrong number of parameters for function name: '" << *m_proc_name_ptr << "'"; - err << ", expected: "; - err << expected_size; - err << ", actual: "; - err << actual_size; - error(err.str()); - } - - for(int i=0; i<actual_size; i++) { - // Check the types of the parameter - Type* actual_type_ptr = paramTypes[i]; - Type* expected_type_ptr = obj_type_ptr->methodParamType(methodId)[i]; - if (actual_type_ptr != expected_type_ptr) { - (*m_expr_vec_ptr)[i]->error("Type mismatch: expected: " + expected_type_ptr->toString() + - " actual: " + actual_type_ptr->toString()); - } - } - - // Return the return type of the method - return obj_type_ptr->methodReturnType(methodId); -} - -void MethodCallExprAST::findResources(Map<Var*, string>& resource_list) const -{ - -} - -void MethodCallExprAST::print(ostream& out) const -{ - out << "[MethodCallExpr: " << *m_proc_name_ptr << *m_obj_expr_ptr << " " << *m_expr_vec_ptr << "]"; -} diff --git a/src/mem/slicc/ast/MethodCallExprAST.hh b/src/mem/slicc/ast/MethodCallExprAST.hh deleted file mode 100644 index d248e6ba4..000000000 --- a/src/mem/slicc/ast/MethodCallExprAST.hh +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * MethodCallExprAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef MethodCallExprAST_H -#define MethodCallExprAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class MethodCallExprAST : public ExprAST { -public: - // Constructors - MethodCallExprAST(ExprAST* m_obj_expr_ptr, - string* proc_name_ptr, - Vector<ExprAST*>* expr_vec_ptr); - - MethodCallExprAST(TypeAST* type_ptr, - string* proc_name_ptr, - Vector<ExprAST*>* expr_vec_ptr); - - // Destructor - ~MethodCallExprAST(); - - // Public Methods - Type* generate(string& code) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - MethodCallExprAST(const MethodCallExprAST& obj); - MethodCallExprAST& operator=(const MethodCallExprAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_obj_expr_ptr; - TypeAST* m_type_ptr; - string* m_proc_name_ptr; - Vector<ExprAST*>* m_expr_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const MethodCallExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const MethodCallExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif // MethodCallExprAST_H diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py new file mode 100644 index 000000000..3f9b250c1 --- /dev/null +++ b/src/mem/slicc/ast/MethodCallExprAST.py @@ -0,0 +1,130 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.ExprAST import ExprAST + +class MethodCallExprAST(ExprAST): + def __init__(self, slicc, proc_name, expr_ast_vec): + super(MethodCallExprAST, self).__init__(slicc) + self.proc_name = proc_name + self.expr_ast_vec = expr_ast_vec + + def generate(self, code): + tmp = code_formatter() + paramTypes = [] + for expr_ast in self.expr_ast_vec: + return_type = expr_ast.generate(tmp) + paramTypes.append(return_type) + + obj_type, methodId, prefix = self.generate_prefix(paramTypes) + + # generate code + params = [] + for expr_ast in self.expr_ast_vec: + return_type,tcode = expr_ast.inline(True) + params.append(str(tcode)) + fix = code.nofix() + code("$prefix${{self.proc_name}}(${{', '.join(params)}}))") + code.fix(fix) + + # Verify that this is a method of the object + if methodId not in obj_type.methods: + self.error("Invalid method call: Type '%s' does not have a method '%s'", + obj_type, methodId) + + if len(self.expr_ast_vec) != \ + len(obj_type.methods[methodId].param_types): + # Right number of parameters + self.error("Wrong number of parameters for function name: '%s', " + \ + "expected: , actual: ", proc_name, + len(obj_type.methods[methodId].param_types), + len(self.expr_ast_vec)) + + for actual_type, expected_type in \ + zip(paramTypes, obj_type.methods[methodId].param_types): + if actual_type != expected_type: + self.error("Type mismatch: expected: %s actual: %s", + expected_type, actual_type) + + # Return the return type of the method + return obj_type.methods[methodId].return_type + + def findResources(self, resources): + pass + +class MemberMethodCallExprAST(MethodCallExprAST): + def __init__(self, slicc, obj_expr_ast, proc_name, expr_ast_vec): + s = super(MemberMethodCallExprAST, self) + s.__init__(slicc, proc_name, expr_ast_vec) + + self.obj_expr_ast = obj_expr_ast + + def __repr__(self): + return "[MethodCallExpr: %r%r %r]" % (self.proc_name, + self.obj_expr_ast, + self.expr_ast_vec) + def generate_prefix(self, paramTypes): + code = code_formatter() + + # member method call + obj_type = self.obj_expr_ast.generate(code) + methodId = obj_type.methodId(self.proc_name, paramTypes) + + prefix = "" + if methodId not in obj_type.methods: + self.error("Invalid method call: Type '%s' does not have a method '%s'", + obj_type, methodId) + return_type = obj_type.methods[methodId].return_type + if return_type.isInterface: + prefix = "static_cast<%s &>" % return_type.c_ident + prefix = "%s((%s)." % (prefix, code) + + return obj_type, methodId, prefix + + +class ClassMethodCallExprAST(MethodCallExprAST): + def __init__(self, slicc, type_ast, proc_name, expr_ast_vec): + s = super(ClassMethodCallExprAST, self) + s.__init__(slicc, proc_name, expr_ast_vec) + + self.type_ast = type_ast + + def __repr__(self): + return "[MethodCallExpr: %r %r]" % (self.proc_name, self.expr_ast_vec) + + def generate_prefix(self, paramTypes): + + # class method call + prefix = "(%s::" % self.type_ast + obj_type = self.type_ast.type + methodId = obj_type.methodId(self.proc_name, paramTypes) + + return obj_type, methodId, prefix + +__all__ = [ "MemberMethodCallExprAST", "ClassMethodCallExprAST" ] diff --git a/src/mem/slicc/ast/NewExprAST.cc b/src/mem/slicc/ast/NewExprAST.cc deleted file mode 100644 index 95e57192f..000000000 --- a/src/mem/slicc/ast/NewExprAST.cc +++ /dev/null @@ -1,9 +0,0 @@ - -#include "mem/slicc/ast/NewExprAST.hh" - -Type* NewExprAST::generate(string & code) const -{ - Type* type = m_type_ptr->lookupType(); - code += "new " + type->cIdent(); - return type; -} diff --git a/src/mem/slicc/ast/NewExprAST.hh b/src/mem/slicc/ast/NewExprAST.hh deleted file mode 100644 index 375f130d6..000000000 --- a/src/mem/slicc/ast/NewExprAST.hh +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef NEWEXPRAST_H -#define NEWEXPRAST_H - -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/symbols/Type.hh" - -class NewExprAST : public ExprAST -{ -public: - NewExprAST(TypeAST* type_ptr) : ExprAST() { m_type_ptr = type_ptr; } - Type* generate(string & code) const; - void print(ostream & out) const { out << "[NewExprAST: " << *m_type_ptr << "]"; } - string getName() const { return m_type_ptr->toString(); } - -private: - TypeAST* m_type_ptr; -}; - -#endif diff --git a/src/mem/slicc/ast/NewExprAST.py b/src/mem/slicc/ast/NewExprAST.py new file mode 100644 index 000000000..a42350768 --- /dev/null +++ b/src/mem/slicc/ast/NewExprAST.py @@ -0,0 +1,47 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST + +class NewExprAST(ExprAST): + def __init__(self, slicc, type_ast): + super(NewExprAST, self).__init__(slicc) + self.type_ast = type_ast + + def __repr__(self): + return "[NewExprAST: %r]" % self.type_ast + + @property + def name(self): + return str(self.type_ast) + + def generate(self, code): + type = self.type_ast.type + fix = code.nofix() + code("new ${{type.c_ident}}") + code.fix(fix) + return type diff --git a/src/mem/slicc/ast/ObjDeclAST.cc b/src/mem/slicc/ast/ObjDeclAST.cc deleted file mode 100644 index 3569395db..000000000 --- a/src/mem/slicc/ast/ObjDeclAST.cc +++ /dev/null @@ -1,137 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ObjDeclAST.cc - * - * Description: See ObjDeclAST.hh - * - * $Id: ObjDeclAST.cc,v 3.13 2004/06/24 15:56:14 beckmann Exp $ - * - */ - -#include "mem/slicc/ast/ObjDeclAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/main.hh" - -ObjDeclAST::ObjDeclAST(TypeAST* type_ptr, - string* ident_ptr, - PairListAST* pairs_ptr) - : DeclAST(pairs_ptr) -{ - m_type_ptr = type_ptr; - m_ident_ptr = ident_ptr; -} - -ObjDeclAST::~ObjDeclAST() -{ - delete m_type_ptr; - delete m_ident_ptr; -} - -void ObjDeclAST::generate() -{ - - bool machineComponentSym = false; - - getPairs().add("chip_object", "yes"); - - string c_code; - - - if (getPairs().exist("hack")) { - warning("'hack=' is now deprecated"); - } - - if (getPairs().exist("network")) { - if (!getPairs().exist("virtual_network")) { - error("Network queues require a 'virtual_network' attribute."); - } - } - - Type* type_ptr = m_type_ptr->lookupType(); - if (type_ptr->isBuffer()) { - if (!getPairs().exist("ordered")) { - error("Buffer object declarations require an 'ordered' attribute."); - } - } - - if (getPairs().exist("ordered")) { - string value = getPairs().lookup("ordered"); - if (value != "true" && value != "false") { - error("The 'ordered' attribute must be 'true' or 'false'."); - } - } - - if (getPairs().exist("random")) { - string value = getPairs().lookup("random"); - if (value != "true" && value != "false") { - error("The 'random' attribute must be 'true' or 'false'."); - } - } - - string machine; - if (g_sym_table.getStateMachine() != NULL) { - machine = g_sym_table.getStateMachine()->getIdent() + "_"; - } - - // FIXME : should all use accessors here to avoid public member variables - if (*m_ident_ptr == "id") { - c_code = "m_chip_ptr->getID()"; - } else if (*m_ident_ptr == "version") { - c_code = "m_version"; - } else if (*m_ident_ptr == "machineID") { - c_code = "m_machineID"; - } else { - c_code = "(*m_" + machine + *m_ident_ptr + "_ptr)"; - // c_code = "(*(m_chip_ptr->m_" + machine + *m_ident_ptr + "_ptr))"; - // machineComponentSym = true; - } - - Var* v = new Var(*m_ident_ptr, getLocation(), type_ptr, c_code, - getPairs(), g_sym_table.getStateMachine()); - - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr != NULL) { - machine_ptr->addObj(v); - }// else { - g_sym_table.newSym(v); - //} - - // used to cheat-- that is, access components in other machines - if (machineComponentSym) { - g_sym_table.newMachComponentSym(v); - } - -} - -void ObjDeclAST::print(ostream& out) const -{ - out << "[ObjDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/ObjDeclAST.hh b/src/mem/slicc/ast/ObjDeclAST.hh deleted file mode 100644 index 0b808f472..000000000 --- a/src/mem/slicc/ast/ObjDeclAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ObjDeclAST.hh - * - * Description: - * - * $Id: ObjDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef ObjDeclAST_H -#define ObjDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class ObjDeclAST : public DeclAST { -public: - // Constructors - ObjDeclAST(TypeAST* type_ptr, - string* ident_ptr, - PairListAST* pairs_ptr); - - // Destructor - ~ObjDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ObjDeclAST(const ObjDeclAST& obj); - ObjDeclAST& operator=(const ObjDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_type_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ObjDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ObjDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ObjDeclAST_H diff --git a/src/mem/slicc/ast/ObjDeclAST.py b/src/mem/slicc/ast/ObjDeclAST.py new file mode 100644 index 000000000..8a967f7b8 --- /dev/null +++ b/src/mem/slicc/ast/ObjDeclAST.py @@ -0,0 +1,94 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Var + +class ObjDeclAST(DeclAST): + def __init__(self, slicc, type_ast, ident, pairs): + super(ObjDeclAST, self).__init__(slicc, pairs) + + self.type_ast = type_ast + self.ident = ident + + def __repr__(self): + return "[ObjDecl: %r]" % self.ident + + def generate(self): + machineComponentSym = False + + self["chip_object"] = "yes" + + if "hack" in self: + warning("'hack=' is now deprecated") + + if "network" in self and "virtual_network" not in self: + self.error("Network queues require a 'virtual_network' attribute") + + type = self.type_ast.type + if type.isBuffer and "ordered" not in self: + self.error("Buffer object decls require an 'ordered' attribute") + + if "ordered" in self: + value = self["ordered"] + + if value not in ("true", "false"): + self.error("The 'ordered' attribute is '%s' " + \ + "must be 'true' or 'false'.", value) + + if "random" in self: + value = self["random"] + if value not in ("true", "false"): + self.error("The 'random' attribute is '%s' " + \ + "must be 'true' or 'false'.", value) + + machine = self.symtab.state_machine + + # FIXME : should all use accessors here to avoid public member + # variables + if self.ident == "id": + c_code = "m_chip_ptr.getID()" + elif self.ident == "version": + c_code = "m_version" + elif self.ident == "machineID": + c_code = "m_machineID" + elif machine: + c_code = "(*m_%s_%s_ptr)" % (machine.ident, self.ident) + else: + c_code = "(*m_%s_ptr)" % (self.ident) + + v = Var(self.symtab, self.ident, self.location, type, c_code, + self.pairs, machine) + + if machine: + machine.addObject(v) + + self.symtab.newSymbol(v) + + # used to cheat-- that is, access components in other machines + if machineComponentSym: + self.symtab.newMachComponentSym(v) diff --git a/src/mem/slicc/ast/OutPortDeclAST.cc b/src/mem/slicc/ast/OutPortDeclAST.cc deleted file mode 100644 index 56a377f23..000000000 --- a/src/mem/slicc/ast/OutPortDeclAST.cc +++ /dev/null @@ -1,79 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutPortDeclAST.C - * - * Description: See OutPortDeclAST.hh - * - * $Id: OutPortDeclAST.C,v 3.3 2004/02/02 22:37:51 milo Exp $ - * - */ - -#include "mem/slicc/ast/OutPortDeclAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -OutPortDeclAST::OutPortDeclAST(string* ident_ptr, - TypeAST* msg_type_ptr, - ExprAST* var_expr_ptr, - PairListAST* pairs_ptr) - : DeclAST(pairs_ptr) -{ - m_ident_ptr = ident_ptr; - m_msg_type_ptr = msg_type_ptr; - m_var_expr_ptr = var_expr_ptr; - m_queue_type_ptr = new TypeAST(new string("OutPort")); -} - -OutPortDeclAST::~OutPortDeclAST() -{ - delete m_ident_ptr; - delete m_msg_type_ptr; - delete m_var_expr_ptr; - delete m_queue_type_ptr; -} - -void OutPortDeclAST::generate() -{ - string code; - Type* queue_type_ptr = m_var_expr_ptr->generate(code); - if (!queue_type_ptr->isOutPort()) { - error("Outport queues must be of a type that has the 'outport' attribute. The type '" + - queue_type_ptr->toString() + "' does not have this attribute."); - } - - Type* type_ptr = m_queue_type_ptr->lookupType(); - g_sym_table.newSym(new Var(*m_ident_ptr, getLocation(), type_ptr, code, getPairs())); -} - - -void OutPortDeclAST::print(ostream& out) const -{ - out << "[OutPortDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/OutPortDeclAST.hh b/src/mem/slicc/ast/OutPortDeclAST.hh deleted file mode 100644 index 0aa0172d3..000000000 --- a/src/mem/slicc/ast/OutPortDeclAST.hh +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutPortDeclAST.hh - * - * Description: - * - * $Id: OutPortDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef OutPortDeclAST_H -#define OutPortDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" - -class OutPortDeclAST : public DeclAST { -public: - // Constructors - OutPortDeclAST(string* ident_ptr, - TypeAST* msg_type_ptr, - ExprAST* var_expr_ptr, - PairListAST* pairs_ptr); - - // Destructor - ~OutPortDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - OutPortDeclAST(const OutPortDeclAST& obj); - OutPortDeclAST& operator=(const OutPortDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_msg_type_ptr; - TypeAST* m_queue_type_ptr; - ExprAST* m_var_expr_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const OutPortDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const OutPortDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //OutPortDeclAST_H diff --git a/src/mem/slicc/ast/OutPortDeclAST.py b/src/mem/slicc/ast/OutPortDeclAST.py new file mode 100644 index 000000000..e6ef31928 --- /dev/null +++ b/src/mem/slicc/ast/OutPortDeclAST.py @@ -0,0 +1,57 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.DeclAST import DeclAST +from slicc.ast.TypeAST import TypeAST +from slicc.symbols import Var + +class OutPortDeclAST(DeclAST): + def __init__(self, slicc, ident, msg_type, var_expr, pairs): + super(OutPortDeclAST, self).__init__(slicc, pairs) + + self.ident = ident + self.msg_type = msg_type + self.var_expr = var_expr + self.queue_type = TypeAST(slicc, "OutPort") + + def __repr__(self): + return "[OutPortDecl: %r]" % self.ident + + def generate(self): + code = code_formatter(newlines=False) + + queue_type = self.var_expr.generate(code) + if not queue_type.isOutPort: + self.error("The outport queue's type must have the 'outport' " + + "attribute. Type '%s' does not have this attribute.", + (queue_type)) + + var = Var(self.symtab, self.ident, self.location, self.queue_type.type, + str(code), self.pairs) + self.symtab.newSymbol(var) diff --git a/src/mem/slicc/ast/PairAST.hh b/src/mem/slicc/ast/PairAST.hh deleted file mode 100644 index d1bb99b93..000000000 --- a/src/mem/slicc/ast/PairAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PairAST.hh - * - * Description: - * - * $Id: PairAST.hh,v 3.1 2001/12/12 01:00:24 milo Exp $ - * - */ - -#ifndef PAIRAST_H -#define PAIRAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" - -class PairAST : public AST { -public: - // Constructors - PairAST(string* key_ptr, string* value_ptr); - PairAST(string key, string* value_ptr); - PairAST(string key, string value); - - // Destructor - ~PairAST(); - - // Public Methods - string key() const { return *m_key_ptr; } - string value() const { return *m_value_ptr; } - - virtual void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - // PairAST(const PairAST& obj); - // PairAST& operator=(const PairAST& obj); - - // Data Members (m_ prefix) - string* m_key_ptr; - string* m_value_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const PairAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const PairAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //PAIRAST_H diff --git a/src/mem/slicc/ast/PairAST.py b/src/mem/slicc/ast/PairAST.py new file mode 100644 index 000000000..347f4d361 --- /dev/null +++ b/src/mem/slicc/ast/PairAST.py @@ -0,0 +1,36 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class PairAST(AST): + def __init__(self, slicc, key, value): + super(PairAST, self).__init__(slicc) + self.key = key + self.value = value + + def __repr__(self): + return '[%s=%s]' % (self.key, self.value) diff --git a/src/mem/slicc/ast/PairListAST.py b/src/mem/slicc/ast/PairListAST.py new file mode 100644 index 000000000..6afe3f4fa --- /dev/null +++ b/src/mem/slicc/ast/PairListAST.py @@ -0,0 +1,37 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class PairListAST(AST): + def __init__(self, slicc): + super(PairListAST, self).__init__(slicc) + + def __repr__(self): + return "[PairListAST] %r" % self.pairs + + def addPair(self, pair_ast): + self[pair_ast.key] = pair_ast.value diff --git a/src/mem/slicc/ast/PeekStatementAST.cc b/src/mem/slicc/ast/PeekStatementAST.cc deleted file mode 100644 index 3e92446dd..000000000 --- a/src/mem/slicc/ast/PeekStatementAST.cc +++ /dev/null @@ -1,115 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PeekStatementAST.C - * - * Description: See PeekStatementAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/PeekStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" - -PeekStatementAST::PeekStatementAST(VarExprAST* queue_name_ptr, - TypeAST* type_ptr, - StatementListAST* statementlist_ptr, - string method) - : StatementAST() -{ - m_queue_name_ptr = queue_name_ptr; - m_type_ptr = type_ptr; - m_statementlist_ptr = statementlist_ptr; - m_method = method; -} - -PeekStatementAST::~PeekStatementAST() -{ - delete m_queue_name_ptr; - delete m_type_ptr; - delete m_statementlist_ptr; -} - -void PeekStatementAST::generate(string& code, Type* return_type_ptr) const -{ - code += indent_str() + "{\n"; // Start scope - inc_indent(); - g_sym_table.pushFrame(); - - Type* msg_type_ptr = m_type_ptr->lookupType(); - - // Add new local var to symbol table - g_sym_table.newSym(new Var("in_msg", getLocation(), msg_type_ptr, "(*in_msg_ptr)", getPairs())); - - // Check the queue type - m_queue_name_ptr->assertType("InPort"); - - // Declare the new "in_msg_ptr" variable - code += indent_str() + "const " + msg_type_ptr->cIdent() + "* in_msg_ptr;\n"; // Declare message - // code += indent_str() + "in_msg_ptr = static_cast<const "; - code += indent_str() + "in_msg_ptr = dynamic_cast<const "; - code += msg_type_ptr->cIdent() + "*>("; - code += "(" + m_queue_name_ptr->getVar()->getCode() + ")"; - code += "."; - code += m_method; - code += "());\n"; - - code += indent_str() + "assert(in_msg_ptr != NULL);\n"; // Check the cast result - - if(CHECK_INVALID_RESOURCE_STALLS) { - // Declare the "in_buffer_rank" variable - code += indent_str() + "int in_buffer_rank = "; // Declare message - code += "(" + m_queue_name_ptr->getVar()->getCode() + ")"; - code += ".getPriority();\n"; - } - - m_statementlist_ptr->generate(code, return_type_ptr); // The other statements - dec_indent(); - g_sym_table.popFrame(); - code += indent_str() + "}\n"; // End scope -} - -void PeekStatementAST::findResources(Map<Var*, string>& resource_list) const -{ - m_statementlist_ptr->findResources(resource_list); -} - -void PeekStatementAST::print(ostream& out) const -{ - out << "[PeekStatementAST: " << m_method - << " queue_name: " << *m_queue_name_ptr - << " type: " << m_type_ptr->toString() - << " " << *m_statementlist_ptr - << "]"; -} diff --git a/src/mem/slicc/ast/PeekStatementAST.hh b/src/mem/slicc/ast/PeekStatementAST.hh deleted file mode 100644 index e8c65ce4f..000000000 --- a/src/mem/slicc/ast/PeekStatementAST.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PeekStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef PEEKSTATEMENTAST_H -#define PEEKSTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" - -class StatementListAST; -class TypeAST; -class VarExprAST; - -class PeekStatementAST : public StatementAST { -public: - // Constructors - PeekStatementAST(VarExprAST* queue_name_ptr, - TypeAST* type_ptr, - StatementListAST* statementlist_ptr, - string method); - // Destructor - ~PeekStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - PeekStatementAST(const PeekStatementAST& obj); - PeekStatementAST& operator=(const PeekStatementAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_queue_name_ptr; - TypeAST* m_type_ptr; - StatementListAST* m_statementlist_ptr; - string m_method; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const PeekStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const PeekStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //PEEKSTATEMENTAST_H diff --git a/src/mem/slicc/ast/PeekStatementAST.py b/src/mem/slicc/ast/PeekStatementAST.py new file mode 100644 index 000000000..5186bf0d5 --- /dev/null +++ b/src/mem/slicc/ast/PeekStatementAST.py @@ -0,0 +1,73 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST +from slicc.symbols import Var + +class PeekStatementAST(StatementAST): + def __init__(self, slicc, queue_name, type_ast, statements, method): + super(PeekStatementAST, self).__init__(slicc) + + self.queue_name = queue_name + self.type_ast = type_ast + self.statements = statements + self.method = method + + def __repr__(self): + return "[PeekStatementAST: %r queue_name: %r type: %r %r]" % \ + (self.method, self.queue_name, self.type_ast, self.statements) + + def generate(self, code, return_type): + self.symtab.pushFrame() + + msg_type = self.type_ast.type + + # Add new local var to symbol table + var = Var(self.symtab, "in_msg", self.location, msg_type, "(*in_msg_ptr)", + self.pairs) + self.symtab.newSymbol(var) + + # Check the queue type + self.queue_name.assertType("InPort") + + # Declare the new "in_msg_ptr" variable + mtid = msg_type.ident + qcode = self.queue_name.var.code + code(''' +{ + const $mtid* in_msg_ptr; + in_msg_ptr = dynamic_cast<const $mtid *>(($qcode).${{self.method}}()); + assert(in_msg_ptr != NULL); +''') + + # The other statements + self.statements.generate(code, return_type) + self.symtab.popFrame() + code("}") + + def findResources(self, resources): + self.statements.findResources(resources) diff --git a/src/mem/slicc/ast/ReturnStatementAST.cc b/src/mem/slicc/ast/ReturnStatementAST.cc deleted file mode 100644 index 8ec937c87..000000000 --- a/src/mem/slicc/ast/ReturnStatementAST.cc +++ /dev/null @@ -1,79 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ReturnStatementAST.C - * - * Description: See ReturnStatementAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/ReturnStatementAST.hh" - -ReturnStatementAST::ReturnStatementAST(ExprAST* expr_ptr) - : StatementAST() -{ - m_expr_ptr = expr_ptr; -} - -ReturnStatementAST::~ReturnStatementAST() -{ - delete m_expr_ptr; -} - -void ReturnStatementAST::generate(string& code, Type* return_type_ptr) const -{ - code += indent_str(); - code += "return "; - Type* actual_type_ptr = m_expr_ptr->generate(code); - code += ";\n"; - - // Is return valid here? - if (return_type_ptr == NULL) { - error("Invalid 'return' statement"); - } - - // The return type must match the return_type_ptr - if (return_type_ptr != actual_type_ptr) { - m_expr_ptr->error("Return type miss-match, expected return type is '" + return_type_ptr->toString() + - "', actual is '" + actual_type_ptr->toString() + "'"); - } -} - -void ReturnStatementAST::findResources(Map<Var*, string>& resource_list) const -{ - m_expr_ptr->findResources(resource_list); -} - -void ReturnStatementAST::print(ostream& out) const -{ - out << "[ReturnStatementAST: " << *m_expr_ptr << "]"; -} diff --git a/src/mem/slicc/ast/ReturnStatementAST.hh b/src/mem/slicc/ast/ReturnStatementAST.hh deleted file mode 100644 index 1fa1b36d6..000000000 --- a/src/mem/slicc/ast/ReturnStatementAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ReturnStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef ReturnStatementAST_H -#define ReturnStatementAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - -class ReturnStatementAST : public StatementAST { -public: - // Constructors - ReturnStatementAST(ExprAST* expr_ptr); - - // Destructor - ~ReturnStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ReturnStatementAST(const ReturnStatementAST& obj); - ReturnStatementAST& operator=(const ReturnStatementAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_expr_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ReturnStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ReturnStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ReturnStatementAST_H diff --git a/src/mem/slicc/ast/ReturnStatementAST.py b/src/mem/slicc/ast/ReturnStatementAST.py new file mode 100644 index 000000000..f1aff1c32 --- /dev/null +++ b/src/mem/slicc/ast/ReturnStatementAST.py @@ -0,0 +1,54 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST + +class ReturnStatementAST(StatementAST): + def __init__(self, slicc, expr_ast): + super(ReturnStatementAST, self).__init__(slicc) + + self.expr_ast = expr_ast + + def __repr__(self): + return "[ReturnStatementAST: %r]" % self.expr_ast + + def generate(self, code, return_type): + actual_type, ecode = self.expr_ast.inline(True) + code('return $ecode;') + + # Is return valid here? + if return_type is None: + self.error("Invalid 'return' statement") + + # The return type must match + if return_type != actual_type: + self.expr_ast.error("Return type miss-match, expected return " + + "type is '%s', actual is '%s'", + return_type, actual_type) + + def findResources(self, resources): + self.expr_ast.findResources(resources) diff --git a/src/mem/slicc/ast/StatementAST.hh b/src/mem/slicc/ast/StatementAST.hh deleted file mode 100644 index 9946541d3..000000000 --- a/src/mem/slicc/ast/StatementAST.hh +++ /dev/null @@ -1,88 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * StatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef STATEMENTAST_H -#define STATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" - -void inc_indent(); -void dec_indent(); -string indent_str(); - -class StatementAST : public AST { -public: - // Constructors - StatementAST() : AST() {} - StatementAST(Map<string, string> pairs) : AST(pairs) {} - - // Destructor - //~StatementAST(); - - // Public Methods - virtual void generate(string& code, Type* return_type_ptr) const = 0; - virtual void findResources(Map<Var*, string>& resource_list) const { } - - //void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - //StatementAST(const StatementAST& obj); - //StatementAST& operator=(const StatementAST& obj); - - // Data Members (m_ prefix) - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const StatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const StatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //STATEMENTAST_H diff --git a/src/mem/slicc/ast/StatementAST.py b/src/mem/slicc/ast/StatementAST.py new file mode 100644 index 000000000..017b2b1ed --- /dev/null +++ b/src/mem/slicc/ast/StatementAST.py @@ -0,0 +1,34 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class StatementAST(AST): + def __init__(self, slicc, pairs=None): + super(StatementAST, self).__init__(slicc, pairs) + + def findResources(self, resources): + pass diff --git a/src/mem/slicc/ast/StatementListAST.cc b/src/mem/slicc/ast/StatementListAST.cc deleted file mode 100644 index 0f5817f7c..000000000 --- a/src/mem/slicc/ast/StatementListAST.cc +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * StatementListAST.C - * - * Description: See StatementListAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/StatementListAST.hh" - -StatementListAST::StatementListAST(Vector<StatementAST*>* vec_ptr) - : AST() -{ - assert(vec_ptr != NULL); - m_vec_ptr = vec_ptr; -} - -// Singleton constructor. -StatementListAST::StatementListAST(StatementAST* statement_ptr) - : AST() -{ - assert(statement_ptr != NULL); - m_vec_ptr = new Vector<StatementAST*>; - m_vec_ptr->insertAtTop(statement_ptr); -} - -StatementListAST::~StatementListAST() -{ - int size = m_vec_ptr->size(); - for(int i=0; i<size; i++) { - delete (*m_vec_ptr)[i]; - } - delete m_vec_ptr; -} - -void StatementListAST::generate(string& code, Type* return_type_ptr) const -{ - int size = m_vec_ptr->size(); - for(int i=0; i<size; i++) { - (*m_vec_ptr)[i]->generate(code, return_type_ptr); - } -} - -void StatementListAST::findResources(Map<Var*, string>& resource_list) const -{ - int size = m_vec_ptr->size(); - for(int i=0; i<size; i++) { - (*m_vec_ptr)[i]->findResources(resource_list); - } -} - -void StatementListAST::print(ostream& out) const -{ - assert(m_vec_ptr != NULL); - out << "[StatementListAST: " << *m_vec_ptr << "]"; -} diff --git a/src/mem/slicc/ast/StatementListAST.hh b/src/mem/slicc/ast/StatementListAST.hh deleted file mode 100644 index 831e2481a..000000000 --- a/src/mem/slicc/ast/StatementListAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * StatementListAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef STATEMENTLISTAST_H -#define STATEMENTLISTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" -#include "mem/slicc/ast/StatementAST.hh" -class Var; - -class StatementListAST : public AST { -public: - // Constructors - StatementListAST(Vector<StatementAST*>* vec_ptr); - StatementListAST(StatementAST* statement_ptr); - - // Destructor - ~StatementListAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map<Var*, string>& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - StatementListAST(const StatementListAST& obj); - StatementListAST& operator=(const StatementListAST& obj); - - // Data Members (m_ prefix) - Vector<StatementAST*>* m_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const StatementListAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const StatementListAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //STATEMENTLISTAST_H diff --git a/src/mem/slicc/ast/StatementListAST.py b/src/mem/slicc/ast/StatementListAST.py new file mode 100644 index 000000000..1475c5c97 --- /dev/null +++ b/src/mem/slicc/ast/StatementListAST.py @@ -0,0 +1,46 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class StatementListAST(AST): + def __init__(self, slicc, statements): + super(StatementListAST, self).__init__(slicc) + if not isinstance(statements, (list, tuple)): + statements = [ statements ] + self.statements = statements + + def __repr__(self): + return "[StatementListAST: %r]" % self.statements + + def generate(self, code, return_type): + for statement in self.statements: + statement.generate(code, return_type) + + def findResources(self, resources): + for statement in self.statements: + statement.findResources(resources) diff --git a/src/mem/slicc/ast/TransitionDeclAST.cc b/src/mem/slicc/ast/TransitionDeclAST.cc deleted file mode 100644 index 66b7ca132..000000000 --- a/src/mem/slicc/ast/TransitionDeclAST.cc +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TransitionDeclAST.C - * - * Description: See TransitionDeclAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/TransitionDeclAST.hh" -#include "mem/slicc/symbols/Transition.hh" - -TransitionDeclAST::TransitionDeclAST(Vector<string>* state_list_ptr, - Vector<string>* event_list_ptr, - string* next_state_ptr, - PairListAST* pairs_ptr, - Vector<string>* action_list_ptr) - : DeclAST(pairs_ptr) -{ - m_state_list_ptr = state_list_ptr; - m_event_list_ptr = event_list_ptr; - m_next_state_ptr = next_state_ptr; - m_action_list_ptr = action_list_ptr; -} - -TransitionDeclAST::~TransitionDeclAST() -{ - delete m_state_list_ptr; - delete m_event_list_ptr; - delete m_next_state_ptr; - delete m_action_list_ptr; -} - -void TransitionDeclAST::generate() -{ - Vector<string>& states = *m_state_list_ptr; - Vector<string>& events = *m_event_list_ptr; - - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr == NULL) { - error("Transition declaration not part of a machine."); - } else if (m_next_state_ptr == NULL) { - for (int i=0; i<states.size(); i++) { - for (int j=0; j<events.size(); j++) { - machine_ptr->addTransition(new Transition(states[i], events[j], states[i], *m_action_list_ptr, getLocation(), getPairs())); - } - } - } else { - for (int i=0; i<states.size(); i++) { - for (int j=0; j<events.size(); j++) { - machine_ptr->addTransition(new Transition(states[i], events[j], *m_next_state_ptr, *m_action_list_ptr, getLocation(), getPairs())); - } - } - } -} - -void TransitionDeclAST::print(ostream& out) const -{ - out << "[TransitionDecl: ]"; -} diff --git a/src/mem/slicc/ast/TransitionDeclAST.hh b/src/mem/slicc/ast/TransitionDeclAST.hh deleted file mode 100644 index f07f0a3c2..000000000 --- a/src/mem/slicc/ast/TransitionDeclAST.hh +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TransistionDeclAST.hh - * - * Description: - * - * $Id: TransitionDeclAST.hh,v 3.2 2003/07/10 18:08:07 milo Exp $ - * - */ - -#ifndef TransitionDeclAST_H -#define TransitionDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" - -class TransitionDeclAST : public DeclAST { -public: - // Constructors - TransitionDeclAST(Vector<string>* state_list_ptr, - Vector<string>* event_list_ptr, - string* next_state_ptr, - PairListAST* pairs_ptr, - Vector<string>* action_list_ptr); - - // Destructor - ~TransitionDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - TransitionDeclAST(const TransitionDeclAST& obj); - TransitionDeclAST& operator=(const TransitionDeclAST& obj); - - // Data Members (m_ prefix) - Vector<string>* m_state_list_ptr; - Vector<string>* m_event_list_ptr; - string* m_next_state_ptr; - Vector<string>* m_action_list_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TransitionDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TransitionDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TransitionDeclAST_H diff --git a/src/mem/slicc/ast/TransitionDeclAST.py b/src/mem/slicc/ast/TransitionDeclAST.py new file mode 100644 index 000000000..a941d7b0c --- /dev/null +++ b/src/mem/slicc/ast/TransitionDeclAST.py @@ -0,0 +1,65 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Transition + +class TransitionDeclAST(DeclAST): + def __init__(self, slicc, states, events, next_state, pairs, actions): + super(TransitionDeclAST, self).__init__(slicc, pairs) + + self.states = states + self.events = events + self.next_state = next_state + self.actions = actions + + def __repr__(self): + return "[TransitionDecl: ]" + + def generate(self): + machine = self.symtab.state_machine + + if machine is None: + self.error("Transition declaration not part of a machine.") + + for action in self.actions: + if action not in machine.actions: + self.error("Invalid action: %s is not part of machine: %s" % \ + (action, machine)) + + for state in self.states: + if state not in machine.states: + self.error("Invalid state: %s is not part of machine: %s" % \ + (state, machine)) + next_state = self.next_state or state + for event in self.events: + if event not in machine.events: + self.error("Invalid event: %s is not part of machine: %s" % \ + (event, machine)) + t = Transition(self.symtab, machine, state, event, next_state, + self.actions, self.location, self.pairs) + machine.addTransition(t) diff --git a/src/mem/slicc/ast/TypeAST.py b/src/mem/slicc/ast/TypeAST.py new file mode 100644 index 000000000..209859b8d --- /dev/null +++ b/src/mem/slicc/ast/TypeAST.py @@ -0,0 +1,53 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +from slicc.symbols import Type + +class TypeAST(AST): + def __init__(self, slicc, ident): + super(TypeAST, self).__init__(slicc) + + self.ident = ident + + def __repr__(self): + return self.ident + + def __str__(self): + return self.ident + + @property + def type(self, assert_type=None): + type = self.symtab.find(self.ident, Type) + if not type: + self.error("Type '%s' not declared.", self) + + if assert_type is not None and type != assert_type: + self.error("Type '%s' is should be type '%s'", self, assert_type) + + return type diff --git a/src/mem/slicc/ast/TypeDeclAST.hh b/src/mem/slicc/ast/TypeDeclAST.hh deleted file mode 100644 index 8a72c0406..000000000 --- a/src/mem/slicc/ast/TypeDeclAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeDeclAST.hh - * - * Description: - * - * $Id: TypeDeclAST.hh,v 3.2 2003/03/17 01:55:28 xu Exp $ - * - */ - -#ifndef TypeDeclAST_H -#define TypeDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" - -class TypeDeclAST : public DeclAST { -public: - // Constructors - TypeDeclAST(TypeAST* type_ast_ptr, - PairListAST* pairs_ptr, - Vector<TypeFieldAST*>* field_vec_ptr); - - // Destructor - ~TypeDeclAST(); - - // Public Methods - virtual void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - TypeDeclAST(const TypeDeclAST& obj); - TypeDeclAST& operator=(const TypeDeclAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_type_ast_ptr; - Vector<TypeFieldAST*>* m_field_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TypeDeclAST_H diff --git a/src/mem/slicc/ast/TypeDeclAST.py b/src/mem/slicc/ast/TypeDeclAST.py new file mode 100644 index 000000000..ecdb5949b --- /dev/null +++ b/src/mem/slicc/ast/TypeDeclAST.py @@ -0,0 +1,61 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols.Type import Type + +class TypeDeclAST(DeclAST): + def __init__(self, slicc, type_ast, pairs, field_asts): + super(TypeDeclAST, self).__init__(slicc, pairs) + + self.type_ast = type_ast + self.field_asts = field_asts + + def __repr__(self): + return "[TypeDecl: %r]" % (self.type_ast) + + def files(self, parent=None): + if "external" in self: + return set() + + if parent: + ident = "%s_%s" % (parent, self.type_ast.ident) + else: + ident = self.type_ast.ident + return set(("%s.hh" % ident, "%s.cc" % ident)) + + def generate(self): + ident = str(self.type_ast) + + # Make the new type + new_type = Type(self.symtab, ident, self.location, self.pairs, + self.state_machine) + self.symtab.newSymbol(new_type) + + # Add all of the fields of the type to it + for field in self.field_asts: + field.generate(new_type) diff --git a/src/mem/slicc/ast/TypeFieldAST.hh b/src/mem/slicc/ast/TypeFieldAST.hh deleted file mode 100644 index 144372047..000000000 --- a/src/mem/slicc/ast/TypeFieldAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef TypeFieldAST_H -#define TypeFieldAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/PairListAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - -class TypeFieldAST : public AST { -public: - // Constructors - TypeFieldAST(PairListAST* pairs_ptr); - - // Destructor - virtual ~TypeFieldAST() {} - - // Public Methods - virtual void generate(Type *type_ptr) = 0; - virtual void print(ostream& out) const = 0; -private: - // Private Methods - - // Private copy constructor and assignment operator - // TypeFieldAST(const TypeFieldAST& obj); - // TypeFieldAST& operator=(const TypeFieldAST& obj); - - // Data Members (m_ prefix) -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeFieldAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeFieldAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TypeFieldAST_H diff --git a/src/mem/slicc/ast/TypeFieldAST.py b/src/mem/slicc/ast/TypeFieldAST.py new file mode 100644 index 000000000..7dd4c74aa --- /dev/null +++ b/src/mem/slicc/ast/TypeFieldAST.py @@ -0,0 +1,32 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class TypeFieldAST(AST): + def __init__(self, slicc, pairs): + super(TypeFieldAST, self).__init__(slicc, pairs) diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.cc b/src/mem/slicc/ast/TypeFieldEnumAST.cc deleted file mode 100644 index 1a02f7edd..000000000 --- a/src/mem/slicc/ast/TypeFieldEnumAST.cc +++ /dev/null @@ -1,82 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldEnumAST.C - * - * Description: See TypeFieldEnumAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/TypeFieldEnumAST.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Event.hh" - -TypeFieldEnumAST::TypeFieldEnumAST(string* field_id_ptr, - PairListAST* pairs_ptr) - : TypeFieldAST(pairs_ptr) -{ - m_field_id_ptr = field_id_ptr; - m_pairs_ptr = pairs_ptr; -} - -TypeFieldEnumAST::~TypeFieldEnumAST() -{ - delete m_field_id_ptr; -} - -void TypeFieldEnumAST::generate(Type *type_ptr) -{ - // Add enumeration - if (!type_ptr->enumAdd(*m_field_id_ptr, m_pairs_ptr->getPairs())) { - error("Duplicate enumeration: " + type_ptr->toString() + ":" + *m_field_id_ptr); - } - - // Fill machine info - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (type_ptr->toString() == "State") { - if (machine_ptr == NULL) { - error("State declaration not part of a machine."); - } - machine_ptr->addState(new State(*m_field_id_ptr, getLocation(), getPairs())); - } - if (type_ptr->toString() == "Event") { - if (machine_ptr == NULL) { - error("Event declaration not part of a machine."); - } - machine_ptr->addEvent(new Event(*m_field_id_ptr, getLocation(), getPairs())); - } -} - -void TypeFieldEnumAST::print(ostream& out) const -{ - out << "[TypeFieldEnum: " << *m_field_id_ptr << "]"; -} diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.hh b/src/mem/slicc/ast/TypeFieldEnumAST.hh deleted file mode 100644 index cd02f03bb..000000000 --- a/src/mem/slicc/ast/TypeFieldEnumAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldEnumAST.hh - * - * Description: - * - * $Id: TypeFieldEnumAST.hh,v 3.2 2003/07/10 18:08:07 milo Exp $ - * - */ - -#ifndef TypeFieldEnumAST_H -#define TypeFieldEnumAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/PairListAST.hh" - -class TypeFieldEnumAST : public TypeFieldAST { -public: - // Constructors - TypeFieldEnumAST(string* field_id_ptr, - PairListAST* pairs_ptr); - - // Destructor - ~TypeFieldEnumAST(); - - // Public Methods - void generate(Type *type_ptr); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - TypeFieldEnumAST(const TypeFieldEnumAST& obj); - TypeFieldEnumAST& operator=(const TypeFieldEnumAST& obj); - - // Data Members (m_ prefix) - string* m_field_id_ptr; - PairListAST* m_pairs_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeFieldEnumAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeFieldEnumAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TypeFieldEnumAST_H diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.py b/src/mem/slicc/ast/TypeFieldEnumAST.py new file mode 100644 index 000000000..138fff793 --- /dev/null +++ b/src/mem/slicc/ast/TypeFieldEnumAST.py @@ -0,0 +1,59 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.TypeFieldAST import TypeFieldAST +from slicc.symbols import Event, State + +class TypeFieldEnumAST(TypeFieldAST): + def __init__(self, slicc, field_id, pairs_ast): + super(TypeFieldEnumAST, self).__init__(slicc, pairs_ast) + + self.field_id = field_id + self.pairs_ast = pairs_ast + + def __repr__(self): + return "[TypeFieldEnum: %r]" % self.field_id + + def generate(self, type): + # Add enumeration + if not type.enumAdd(self.field_id, self.pairs_ast.pairs): + self.error("Duplicate enumeration: %s:%s" % (type, self.field_id)) + + # Fill machine info + machine = self.symtab.state_machine + + if str(type) == "State": + if not machine: + self.error("State declaration not part of a machine.") + s = State(self.symtab, self.field_id, self.location, self.pairs) + machine.addState(s) + + if str(type) == "Event": + if not machine: + self.error("Event declaration not part of a machine.") + e = Event(self.symtab, self.field_id, self.location, self.pairs) + machine.addEvent(e) diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.cc b/src/mem/slicc/ast/TypeFieldMemberAST.cc deleted file mode 100644 index 1fe0f6d4b..000000000 --- a/src/mem/slicc/ast/TypeFieldMemberAST.cc +++ /dev/null @@ -1,84 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldMemberAST.C - * - * Description: See TypeFieldMemberAST.hh - * - * $Id: TypeFieldMemberAST.C,v 3.1 2003/03/27 22:58:54 xu Exp $ - * - */ - -#include "mem/slicc/ast/TypeFieldMemberAST.hh" - -TypeFieldMemberAST::TypeFieldMemberAST(TypeAST* type_ast_ptr, - string* field_id_ptr, - PairListAST* pairs_ptr, - ExprAST* rvalue_ptr) - : TypeFieldAST(pairs_ptr) -{ - m_type_ast_ptr = type_ast_ptr; - m_field_id_ptr = field_id_ptr; - m_rvalue_ptr = rvalue_ptr; -} - -TypeFieldMemberAST::~TypeFieldMemberAST() -{ - delete m_type_ast_ptr; - delete m_field_id_ptr; - if(m_rvalue_ptr) delete m_rvalue_ptr; -} - -void TypeFieldMemberAST::generate(Type *type_ptr) -{ - // Lookup type - Type* field_type_ptr = m_type_ast_ptr->lookupType(); - - // check type if this is a initialization - string* init_code = NULL; - if(m_rvalue_ptr) { - init_code = new string(); - Type* rvalue_type_ptr = m_rvalue_ptr->generate(*init_code); - if(field_type_ptr != rvalue_type_ptr) { - error("Initialization type mismatch '" + field_type_ptr->toString() + "' and '" + rvalue_type_ptr->toString() + "'"); - } - } - - // Add data member to the parent type - if (!type_ptr->dataMemberAdd(*m_field_id_ptr, field_type_ptr, getPairs(), - init_code)) { - error("Duplicate data member: " + type_ptr->toString() + ":" + *m_field_id_ptr); - } -} - -void TypeFieldMemberAST::print(ostream& out) const -{ - out << "[TypeFieldMember: " << *m_field_id_ptr << "]"; -} diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.hh b/src/mem/slicc/ast/TypeFieldMemberAST.hh deleted file mode 100644 index 47355f3ac..000000000 --- a/src/mem/slicc/ast/TypeFieldMemberAST.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldMemberAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef TypeFieldMemberAST_H -#define TypeFieldMemberAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/PairListAST.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class TypeFieldMemberAST : public TypeFieldAST { -public: - // Constructors - TypeFieldMemberAST(TypeAST* type_ast_ptr, - string* field_id_ptr, - PairListAST* pairs_ptr, - ExprAST* rvalue_ptr); - - // Destructor - ~TypeFieldMemberAST(); - - // Public Methods - void generate(Type *type_ptr); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - TypeFieldMemberAST(const TypeFieldMemberAST& obj); - TypeFieldMemberAST& operator=(const TypeFieldMemberAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_type_ast_ptr; - string* m_field_id_ptr; - ExprAST* m_rvalue_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeFieldMemberAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeFieldMemberAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TypeFieldMemberAST_H diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.py b/src/mem/slicc/ast/TypeFieldMemberAST.py new file mode 100644 index 000000000..a60153664 --- /dev/null +++ b/src/mem/slicc/ast/TypeFieldMemberAST.py @@ -0,0 +1,57 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.TypeFieldAST import TypeFieldAST + +class TypeFieldMemberAST(TypeFieldAST): + def __init__(self, slicc, type_ast, field_id, pairs, rvalue): + super(TypeFieldMemberAST, self).__init__(slicc, pairs) + + self.type_ast = type_ast + self.field_id = field_id + self.rvalue = rvalue + + def __repr__(self): + return "[TypeFieldMember: %r]" % self.field_id + + def generate(self, type): + # Lookup type + field_type = self.type_ast.type + + # check type if this is a initialization + init_code = "" + if self.rvalue: + rvalue_type,init_code = self.rvalue.inline(True) + if field_type != rvalue_type: + self.error("Initialization type mismatch '%s' and '%s'" % \ + (field_type, rvalue_type)) + + # Add data member to the parent type + if not type.dataMemberAdd(self.field_id, field_type, self.pairs, + init_code): + + self.error("Duplicate data member: %s:%s" % (type_ptr, field_id)) diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.cc b/src/mem/slicc/ast/TypeFieldMethodAST.cc deleted file mode 100644 index 03c528f87..000000000 --- a/src/mem/slicc/ast/TypeFieldMethodAST.cc +++ /dev/null @@ -1,81 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldMethodAST.C - * - * Description: See TypeFieldMethodAST.hh - * - * $Id: TypeFieldMethodAST.C,v 3.1 2003/07/10 18:08:07 milo Exp $ - * - */ - -#include "mem/slicc/ast/TypeFieldMethodAST.hh" - -TypeFieldMethodAST::TypeFieldMethodAST(TypeAST* return_type_ast_ptr, - string* ident_ptr, - Vector<TypeAST*>* type_ast_vec_ptr, - PairListAST* pairs_ptr) - : TypeFieldAST(pairs_ptr) -{ - m_return_type_ast_ptr = return_type_ast_ptr; - m_ident_ptr = ident_ptr; - m_type_ast_vec_ptr = type_ast_vec_ptr; -} - -TypeFieldMethodAST::~TypeFieldMethodAST() -{ - delete m_return_type_ast_ptr; - delete m_ident_ptr; - - int size = m_type_ast_vec_ptr->size(); - for(int i=0; i<size; i++) { - delete (*m_type_ast_vec_ptr)[i]; - } - delete m_type_ast_vec_ptr; -} - -void TypeFieldMethodAST::generate(Type *type_ptr) -{ - // Lookup return type - Type* return_type_ptr = m_return_type_ast_ptr->lookupType(); - - // Lookup parameter types - Vector<Type*> type_vec; - int size = m_type_ast_vec_ptr->size(); - for(int i=0; i<size; i++) { - Type* type_ptr = (*m_type_ast_vec_ptr)[i]->lookupType(); - type_vec.insertAtBottom(type_ptr); - } - - // Add method - if (!type_ptr->methodAdd(*m_ident_ptr, return_type_ptr, type_vec)) { // Return false on error - error("Duplicate method: " + type_ptr->toString() + ":" + *m_ident_ptr + "()"); - } -} diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.hh b/src/mem/slicc/ast/TypeFieldMethodAST.hh deleted file mode 100644 index 10d53ef80..000000000 --- a/src/mem/slicc/ast/TypeFieldMethodAST.hh +++ /dev/null @@ -1,87 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldMethodAST.hh - * - * Description: - * - * $Id: TypeFieldMethodAST.hh,v 3.2 2003/07/10 18:08:07 milo Exp $ - * - */ - -#ifndef TYPEFIELDMETHODAST_H -#define TYPEFIELDMETHODAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class TypeFieldMethodAST : public TypeFieldAST { -public: - // Constructors - TypeFieldMethodAST(TypeAST* return_type_ast_ptr, - string* ident_ptr, - Vector<TypeAST*>* type_ast_vec_ptr, - PairListAST* pairs_ptr); - // Destructor - ~TypeFieldMethodAST(); - - // Public Methods - - void generate(Type *type_ptr); - void print(ostream& out) const {} -private: - // Private Methods - - // Private copy constructor and assignment operator - TypeFieldMethodAST(const TypeFieldMethodAST& obj); - TypeFieldMethodAST& operator=(const TypeFieldMethodAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_return_type_ast_ptr; - string* m_ident_ptr; - Vector<TypeAST*>* m_type_ast_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeFieldMethodAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeFieldMethodAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TYPEFIELDMETHODAST_H diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.py b/src/mem/slicc/ast/TypeFieldMethodAST.py new file mode 100644 index 000000000..2c8cf3f7b --- /dev/null +++ b/src/mem/slicc/ast/TypeFieldMethodAST.py @@ -0,0 +1,50 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.TypeFieldAST import TypeFieldAST + +class TypeFieldMethodAST(TypeFieldAST): + def __init__(self, slicc, return_type_ast, ident, type_asts, pairs): + super(TypeFieldMethodAST, self).__init__(slicc, pairs) + + self.return_type_ast = return_type_ast + self.ident = ident + self.type_asts = type_asts + + def __repr__(self): + return "" + + def generate(self, type): + # Lookup return type + return_type = self.return_type_ast.type + + # Lookup parameter types + types = [ t.type for t in self.type_asts ] + + # Add method + if not type.methodAdd(self.ident, return_type, types): + self.error("Duplicate method: %s:%s()" % (type, self.ident)) diff --git a/src/mem/slicc/ast/VarExprAST.cc b/src/mem/slicc/ast/VarExprAST.cc deleted file mode 100644 index 13e265540..000000000 --- a/src/mem/slicc/ast/VarExprAST.cc +++ /dev/null @@ -1,76 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VarExprAST.C - * - * Description: See VarExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -VarExprAST::~VarExprAST() -{ - delete m_var_ptr; -} - - -Var* VarExprAST::getVar() const -{ - string var = *m_var_ptr; - Var* var_ptr = g_sym_table.getVar(var); - if (var_ptr == NULL) { - error("Unrecognized variable: " + var); - } - return var_ptr; -} - -void VarExprAST::assertType(string type_ident) const -{ - Type* expected_type_ptr = g_sym_table.getType(type_ident); - if (expected_type_ptr == NULL) { - error("There must be a type '" + type_ident + "' declared in this scope"); - } - - if (getVar()->getType() != expected_type_ptr) { - error("Incorrect type: '" + getVar()->getIdent() + "' is expected to be type '" + expected_type_ptr->toString() + "'"); - } -} - -Type* VarExprAST::generate(string& code) const -{ - Var* var_ptr = getVar(); - code += var_ptr->getCode(); - return var_ptr->getType(); -} diff --git a/src/mem/slicc/ast/VarExprAST.hh b/src/mem/slicc/ast/VarExprAST.hh deleted file mode 100644 index ea32582a2..000000000 --- a/src/mem/slicc/ast/VarExprAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VarExprAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef VAREXPRAST_H -#define VAREXPRAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" -class Var; - -class VarExprAST : public ExprAST { -public: - // Constructors - VarExprAST(string* var_ptr) : ExprAST() { m_var_ptr = var_ptr; } - - // Destructor - ~VarExprAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const { out << "[VarExprAST: " << *m_var_ptr << "]"; } - string getName() const { return *m_var_ptr; } - Var* getVar() const; - void assertType(string type_ident) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - VarExprAST(const VarExprAST& obj); - VarExprAST& operator=(const VarExprAST& obj); - - // Data Members (m_ prefix) - string* m_var_ptr; - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const VarExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const VarExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //VAREXPRAST_H diff --git a/src/mem/slicc/ast/VarExprAST.py b/src/mem/slicc/ast/VarExprAST.py new file mode 100644 index 000000000..ac440bb68 --- /dev/null +++ b/src/mem/slicc/ast/VarExprAST.py @@ -0,0 +1,66 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Type, Var + +class VarExprAST(ExprAST): + def __init__(self, slicc, var): + super(VarExprAST, self).__init__(slicc) + self._var = var + + def __repr__(self): + return "[VarExprAST: %r]" % self._var + + @property + def name(self): + return str(self._var) + + @property + def var(self): + var = self.symtab.find(self._var, Var) + if not var: + self.error("Unrecognized variable: %s", self._var) + return var + + def assertType(self, type_ident): + expected_type = self.symtab.find(type_ident, Type) + + if not expected_type: + self.error("There must be a type '%s' declared in this scope", + type_ident) + + if self.var.type != expected_type: + self.error("Incorrect type: " + \ + "'%s' is expected to be type '%s' not '%s'", + self.var.ident, expected_type, self.var.type) + + def generate(self, code): + fix = code.nofix() + code("${{self.var.code}}") + code.fix(fix) + return self.var.type diff --git a/src/mem/slicc/ast/__init__.py b/src/mem/slicc/ast/__init__.py new file mode 100644 index 000000000..de50cbd49 --- /dev/null +++ b/src/mem/slicc/ast/__init__.py @@ -0,0 +1,69 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import * + +# actual ASTs +from slicc.ast.ActionDeclAST import * +from slicc.ast.AssignStatementAST import * +from slicc.ast.CheckAllocateStatementAST import * +from slicc.ast.CheckStopSlotsStatementAST import * +from slicc.ast.ChipComponentAccessAST import * +from slicc.ast.CopyHeadStatementAST import * +from slicc.ast.DeclAST import * +from slicc.ast.DeclListAST import * +from slicc.ast.EnqueueStatementAST import * +from slicc.ast.EnumDeclAST import * +from slicc.ast.EnumExprAST import * +from slicc.ast.ExprAST import * +from slicc.ast.ExprStatementAST import * +from slicc.ast.FormalParamAST import * +from slicc.ast.FuncCallExprAST import * +from slicc.ast.FuncDeclAST import * +from slicc.ast.IfStatementAST import * +from slicc.ast.InPortDeclAST import * +from slicc.ast.InfixOperatorExprAST import * +from slicc.ast.LiteralExprAST import * +from slicc.ast.MachineAST import * +from slicc.ast.MemberExprAST import * +from slicc.ast.MethodCallExprAST import * +from slicc.ast.NewExprAST import * +from slicc.ast.ObjDeclAST import * +from slicc.ast.OutPortDeclAST import * +from slicc.ast.PairAST import * +from slicc.ast.PairListAST import * +from slicc.ast.PeekStatementAST import * +from slicc.ast.ReturnStatementAST import * +from slicc.ast.StatementAST import * +from slicc.ast.StatementListAST import * +from slicc.ast.TransitionDeclAST import * +from slicc.ast.TypeAST import * +from slicc.ast.TypeDeclAST import * +from slicc.ast.TypeFieldAST import * +from slicc.ast.TypeFieldEnumAST import * +from slicc.ast.TypeFieldMemberAST import * +from slicc.ast.TypeFieldMethodAST import * +from slicc.ast.VarExprAST import * diff --git a/src/mem/slicc/generate/__init__.py b/src/mem/slicc/generate/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/mem/slicc/generate/__init__.py diff --git a/src/mem/slicc/generate/dot.py b/src/mem/slicc/generate/dot.py new file mode 100644 index 000000000..762658983 --- /dev/null +++ b/src/mem/slicc/generate/dot.py @@ -0,0 +1,42 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util.code_formatter import code_formatter + +def printDotty(sm, code): + code('digraph ${{sm.getIdent()}} {') + code.indent() + for t in sm.transitions: + # Don't print ignored transitions + if t.getActionShorthands() in ("--", "z"): + continue + + code('${{t.getStateShorthand()}} -> ${{t.getNextStateShorthand()}') + code(' [label="${{t.getEventShorthand()}}/${{t.getActionShorthands()}}"') + code.dedent() + code('}') + diff --git a/src/mem/slicc/generate/html.py b/src/mem/slicc/generate/html.py new file mode 100644 index 000000000..53252ce3c --- /dev/null +++ b/src/mem/slicc/generate/html.py @@ -0,0 +1,80 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util.code_formatter import code_formatter + +def createSymbol(symbol, title): + code = code_formatter() + code('''<HTML><BODY><BIG> +$title: +${{formatShorthand(symbol.short)}} - ${{symbol.desc}}</BIG></BODY></HTML>''') + return code + +def formatShorthand(short): + munged_shorthand = "" + mode_is_normal = True + + # -- Walk over the string, processing superscript directives + gen = enumerate(short) + for i,c in gen: + if c == '!': + # -- Reached logical end of shorthand name + break + elif c == '_': + munged_shorthand += " " + elif c == '^': + # -- Process super/subscript formatting + mode_is_normal = not mode_is_normal + if mode_is_normal: + # -- Back to normal mode + munged_shorthand += "</SUP>" + else: + # -- Going to superscript mode + munged_shorthand += "<SUP>" + elif c == '\\': + # -- Process Symbol character set + if i + 1 < len(short): + # -- Proceed to next char. Yes I know that changing + # the loop var is ugly! + i,c = gen.next() + munged_shorthand += "<B><FONT size=+1>" + munged_shorthand += c + munged_shorthand += "</FONT></B>" + else: + # -- FIXME: Add line number info later + panic("Encountered a `\\` without anything following it!") + else: + # -- Pass on un-munged + munged_shorthand += c + + # -- Do any other munging + if not mode_is_normal: + # -- Back to normal mode + munged_shorthand += "</SUP>" + + return munged_shorthand + diff --git a/src/mem/slicc/generate/tex.py b/src/mem/slicc/generate/tex.py new file mode 100644 index 000000000..97c63ebc6 --- /dev/null +++ b/src/mem/slicc/generate/tex.py @@ -0,0 +1,71 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util.code_formatter import code_formatter + +class tex_formatter(code_formatter): + braced = "<>" + double_braced = "<<>>" + +def printTexTable(sm, code): + tex = tex_formatter() + tex(r''' +%& latex +\documentclass[12pt]{article} +\usepackage{graphics} +\begin{document} +\begin{tabular}{|l||$<<"l" * len(sm.events)>>|} \hline +''') + + for event in sm.events: + code(r" & \rotatebox{90}{$<<event.short>>}") + tex(r'\\ \hline \hline') + + for state in sm.states: + state_str = state.short + for event in sm.events: + state_str += ' & ' + trans = sm.get_transition(state, event) + if trans: + actions = trans.getActionShorthands() + # FIXME: should compare index, not the string + if trans.getNextStateShorthand() != state.short: + nextState = trans.getNextStateShorthand() + else: + nextState = "" + state_str += actions + if nextState and actions: + state_str += '/' + state_str += nextState + tex(r'$0 \\', state_str) + tex(r''' +\hline +\end{tabular} +\end{document} +''') + + code.append(tex) diff --git a/src/mem/slicc/generator/html_gen.cc b/src/mem/slicc/generator/html_gen.cc deleted file mode 100644 index 2d35dccb6..000000000 --- a/src/mem/slicc/generator/html_gen.cc +++ /dev/null @@ -1,125 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * html_gen.C - * - * Description: See html_gen.hh - * - * $Id: html_gen.C,v 3.4 2004/01/31 20:46:50 milo Exp $ - * - * */ - -#include "mem/slicc/generator/html_gen.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -string formatHTMLShorthand(const string shorthand); - - -void createHTMLSymbol(const Symbol& sym, string title, ostream& out) -{ - out << "<HTML><BODY><BIG>" << endl; - out << title << ": " << endl; - out << formatHTMLShorthand(sym.getShorthand()) << " - "; - out << sym.getDescription(); - out << "</BIG></BODY></HTML>" << endl; -} - -void createHTMLindex(string title, ostream& out) -{ - out << "<html>" << endl; - out << "<head>" << endl; - out << "<title>" << title << "</title>" << endl; - out << "</head>" << endl; - out << "<frameset rows=\"*,30\">" << endl; - Vector<StateMachine*> machine_vec = g_sym_table.getStateMachines(); - if (machine_vec.size() > 1) { - string machine = machine_vec[0]->getIdent(); - out << " <frame name=\"Table\" src=\"" << machine << "_table.html\">" << endl; - } else { - out << " <frame name=\"Table\" src=\"empty.html\">" << endl; - } - - out << " <frame name=\"Status\" src=\"empty.html\">" << endl; - out << "</frameset>" << endl; - out << "</html>" << endl; -} - -string formatHTMLShorthand(const string shorthand) -{ - string munged_shorthand = ""; - bool mode_is_normal = true; - - // -- Walk over the string, processing superscript directives - for(unsigned int i = 0; i < shorthand.length(); i++) { - if(shorthand[i] == '!') { - // -- Reached logical end of shorthand name - break; - } else if( shorthand[i] == '_') { - munged_shorthand += " "; - } else if( shorthand[i] == '^') { - // -- Process super/subscript formatting - mode_is_normal = !mode_is_normal; - if(mode_is_normal) { - // -- Back to normal mode - munged_shorthand += "</SUP>"; - } else { - // -- Going to superscript mode - munged_shorthand += "<SUP>"; - } - } else if(shorthand[i] == '\\') { - // -- Process Symbol character set - if((i + 1) < shorthand.length()) { - i++; // -- Proceed to next char. Yes I know that changing the loop var is ugly! - munged_shorthand += "<B><FONT size=+1>"; - munged_shorthand += shorthand[i]; - munged_shorthand += "</FONT></B>"; - } else { - // -- FIXME: Add line number info later - cerr << "Encountered a `\\` without anything following it!" << endl; - exit( -1 ); - } - } else { - // -- Pass on un-munged - munged_shorthand += shorthand[i]; - } - } // -- end for all characters in shorthand - - // -- Do any other munging - if(!mode_is_normal) { - // -- Back to normal mode - munged_shorthand += "</SUP>"; - } - - // -- Return the formatted shorthand name - return munged_shorthand; -} - - diff --git a/src/mem/slicc/generator/html_gen.hh b/src/mem/slicc/generator/html_gen.hh deleted file mode 100644 index 6b1f8ea92..000000000 --- a/src/mem/slicc/generator/html_gen.hh +++ /dev/null @@ -1,49 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * html_gen.hh - * - * Description: - * - * $Id: html_gen.hh,v 3.1 2001/12/12 01:00:35 milo Exp $ - * - * */ - -#ifndef HTML_GEN_H -#define HTML_GEN_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -string formatHTMLShorthand(const string shorthand); -void createHTMLindex(string title, ostream& out); -void createHTMLSymbol(const Symbol& sym, string title, ostream& out); - -#endif //HTML_GEN_H diff --git a/src/mem/slicc/generator/mif_gen.cc b/src/mem/slicc/generator/mif_gen.cc deleted file mode 100644 index 2dca149b4..000000000 --- a/src/mem/slicc/generator/mif_gen.cc +++ /dev/null @@ -1,1718 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/generator/mif_gen.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Event.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/slicc/symbols/Transition.hh" - -// -- Helper functions -string formatShorthand(const string shorthand); -string formatCellRuling(const string shorthand); - -void printStateTableMIF(const StateMachine& sm, ostream& out) -{ - const string mif_prolog1 = -"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\ -<Tbls\n\ - <Tbl\n\ - <TblID 1>\n\ - <TblTag `Format A'>\n\ - <TblFormat\n\ -\n\ - <TblAlignment Center>\n\ -\n\ - # <TblXColumnNum 0>\n\ - <TblXColumnRuling `Medium'>\n\ -\n\ - <TblLRuling `Medium'>\n\ - <TblRRuling `Medium'>\n\ - <TblTRuling `Medium'>\n\ - <TblBRuling `Medium'>\n\ -\n\ - <TblColumn\n\ - <TblColumnNum 0>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnH\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnH\n\ - <TblColumnBody\n\ - <PgfTag `CellBody'>\n\ - > # end of TblColumnBody\n\ - <TblColumnF\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - <TblColumn\n\ - <TblColumnNum 1>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnH\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnH\n\ - <TblColumnBody\n\ - <PgfTag `CellBody'>\n\ - > # end of TblColumnBody\n\ - <TblColumnF\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - > # end of TblFormat\n\ -\n\ - <TblNumColumns 2>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnWidth 6.00\">\n\ - <TblTitle\n\ - <TblTitleContent\n\ - <Para\n\ - <PgfTag `TableTitle'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - <PgfNumString `TABLE 1. '>\n\ - <ParaLine\n\ - <Marker\n\ - <MType 9>\n\ - <MTypeName `Cross-Ref'>\n\ - <MCurrPage `1'>\n\ - > # end of Marker\n\ - <String `"; - - const string mif_prolog2 = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - <TblH\n\ - <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.44444\">\n\ - <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `State'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - <ParaLine\n\ - <String `Description'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ - > # end of TblH\n\ -\n\ - <TblBody\n\ -"; - - const string row_before_state = -" <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.22222\">\n\ - <Cell\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `"; - - const string row_between_state_desc = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - <Cell\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <ParaLine\n\ - <String `"; - - const string row_after_desc = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ -"; - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - <Para\n\ - <ParaLine\n\ - <ATbl 1>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - out << mif_prolog1; - out << formatShorthand( sm.getShorthand() ); - out << " states"; - out << mif_prolog2; - - for( int i = 0; i < sm.numStates(); i++ ) - { - out << row_before_state; - out << formatShorthand( sm.getState( i ).getShorthand() ); - out << row_between_state_desc; - out << sm.getState( i ).getDescription(); - out << row_after_desc; - } - - out << mif_epilog; -} - - -void printEventTableMIF(const StateMachine& sm, ostream& out) -{ - const string mif_prolog1 = -"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\ -<Tbls\n\ - <Tbl\n\ - <TblID 1>\n\ - <TblTag `Format A'>\n\ - <TblFormat\n\ -\n\ - <TblAlignment Center>\n\ -\n\ - # <TblXColumnNum 0>\n\ - <TblXColumnRuling `Medium'>\n\ -\n\ - <TblLRuling `Medium'>\n\ - <TblRRuling `Medium'>\n\ - <TblTRuling `Medium'>\n\ - <TblBRuling `Medium'>\n\ -\n\ - <TblColumn\n\ - <TblColumnNum 0>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnH\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnH\n\ - <TblColumnBody\n\ - <PgfTag `CellBody'>\n\ - > # end of TblColumnBody\n\ - <TblColumnF\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - <TblColumn\n\ - <TblColumnNum 1>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnH\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnH\n\ - <TblColumnBody\n\ - <PgfTag `CellBody'>\n\ - > # end of TblColumnBody\n\ - <TblColumnF\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - > # end of TblFormat\n\ -\n\ - <TblNumColumns 2>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnWidth 6.00\">\n\ - <TblTitle\n\ - <TblTitleContent\n\ - <Para\n\ - <PgfTag `TableTitle'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - <PgfNumString `TABLE 1. '>\n\ - <ParaLine\n\ - <Marker\n\ - <MType 9>\n\ - <MTypeName `Cross-Ref'>\n\ - <MCurrPage `1'>\n\ - > # end of Marker\n\ - <String `"; - const string mif_prolog2 = -"'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - <TblH\n\ - <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.44444\">\n\ - <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `Event'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <ParaLine\n\ - <String `Description'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ - > # end of TblH\n\ -\n\ - <TblBody\n\ -"; - - const string row_before_event = -" <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.22222\">\n\ - <Cell\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `"; - - const string row_between_event_desc = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - <Cell\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <ParaLine\n\ - <String `"; - - const string row_after_desc = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ -"; - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - <Para\n\ - <ParaLine\n\ - <ATbl 1>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - out << mif_prolog1; - out << formatShorthand( sm.getShorthand() ); - out << " events"; - out << mif_prolog2; - - for( int i = 0; i < sm.numEvents(); i++ ) - { - out << row_before_event; - out << formatShorthand( sm.getEvent( i ).getShorthand() ); - out << row_between_event_desc; - out << sm.getEvent( i ).getDescription(); - out << row_after_desc; - } - - out << mif_epilog; -} - - -void printActionTableMIF(const StateMachine& sm, ostream& out) -{ - const string mif_prolog1 = -"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\ -<Tbls\n\ - <Tbl\n\ - <TblID 1>\n\ - <TblTag `Format A'>\n\ - <TblFormat\n\ -\n\ - <TblAlignment Center>\n\ -\n\ - # <TblXColumnNum 0>\n\ - <TblXColumnRuling `Medium'>\n\ -\n\ - <TblLRuling `Medium'>\n\ - <TblRRuling `Medium'>\n\ - <TblTRuling `Medium'>\n\ - <TblBRuling `Medium'>\n\ -\n\ - <TblColumn\n\ - <TblColumnNum 0>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnH\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnH\n\ - <TblColumnBody\n\ - <PgfTag `CellBody'>\n\ - > # end of TblColumnBody\n\ - <TblColumnF\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - <TblColumn\n\ - <TblColumnNum 1>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnH\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnH\n\ - <TblColumnBody\n\ - <PgfTag `CellBody'>\n\ - > # end of TblColumnBody\n\ - <TblColumnF\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - > # end of TblFormat\n\ -\n\ - <TblNumColumns 2>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnWidth 6.00\">\n\ - <TblTitle\n\ - <TblTitleContent\n\ - <Para\n\ - <PgfTag `TableTitle'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - <PgfNumString `TABLE 1. '>\n\ - <ParaLine\n\ - <Marker\n\ - <MType 9>\n\ - <MTypeName `Cross-Ref'>\n\ - <MCurrPage `1'>\n\ - > # end of Marker\n\ - <String `"; - const string mif_prolog2 = -"'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - <TblH\n\ - <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.44444\">\n\ - <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `Action'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <ParaLine\n\ - <String `Description'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ - > # end of TblH\n\ -\n\ - <TblBody\n\ -"; - - const string row_before_action = -" <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.22222\">\n\ - <Cell\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `"; - - const string row_between_action_desc = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - <Cell\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <ParaLine\n\ - <String `"; - - const string row_after_desc = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ -"; - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - <Para\n\ - <ParaLine\n\ - <ATbl 1>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - out << mif_prolog1; - out << formatShorthand( sm.getShorthand() ); - out << " actions"; - out << mif_prolog2; - - for( int i = 0; i < sm.numActions(); i++ ) - { - out << row_before_action; - out << formatShorthand( sm.getAction( i ).getShorthand() ); - out << row_between_action_desc; - out << sm.getAction( i ).getDescription(); - out << row_after_desc; - } - - out << mif_epilog; -} - - -void printTransitionTableMIF(const StateMachine& sm, ostream& out) -{ - const string mif_prolog = -"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\ -<Tbls\n\ - <Tbl\n\ - <TblID 1>\n\ - <TblTag `Format A'>\n\ - <TblFormat\n\ -\n\ - <TblAlignment Center>\n\ -\n\ - # <TblXColumnNum 0>\n\ - <TblXColumnRuling `Medium'>\n\ -\n\ - <TblLRuling `Medium'>\n\ - <TblRRuling `Medium'>\n\ - <TblTRuling `Medium'>\n\ - <TblBRuling `Medium'>\n\ - \n\ -"; - - const string tbl_fmt_before_col_num = -" <TblColumn\n\ - <TblColumnNum "; - - const string tbl_fmt_after_col_num = - ">\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnH\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnH\n\ - <TblColumnBody\n\ - <PgfTag `CellBody'>\n\ - > # end of TblColumnBody\n\ - <TblColumnF\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ -"; - - const string tbl_fmt_before_num_cols = -" > # end of TblFormat\n\ -\n\ - <TblNumColumns "; - - const string tbl_fmt_each_col_width_begin = - ">\n\ - <TblColumnWidth "; - - const string tbl_fmt_each_col_width_end = "\""; - - const string tbl_before_first_header1 = - ">\n\ - <TblTitle\n\ - <TblTitleContent\n\ - <Para\n\ - <PgfTag `TableTitle'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - <PgfNumString `TABLE 1. '>\n\ - <ParaLine\n\ - <Marker\n\ - <MType 9>\n\ - <MTypeName `Cross-Ref'>\n\ - <MCurrPage `1'>\n\ - > # end of Marker\n\ - <String `"; - - const string tbl_before_first_header2 = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - <TblH\n\ - <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.44444\">"; - - const string tbl_before_each_header = -" <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `"; - - const string tbl_before_each_rot_header = -" <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellAngle 270>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <ParaLine\n\ - <String `"; - - const string tbl_after_each_header = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ -"; - - const string before_first_row = -" > # end of Row\n\ - > # end of TblH\n\ -\n\ - <TblBody\n\ -"; - - const string row_before_first_cell = -" <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.22222\">"; - - const string row_cell_before_ruling = -" <Cell\n\ -"; - - const string row_cell_before_contents = -" <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `"; - - const string row_cell_after_contents = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ -"; - - const string row_empty_cell = -" <CellFill 5>\n\ - <CellColor `Cyan'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <ParaLine\n\ - <String `'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ -"; - - const string row_after_last_cell = -" > # end of Row\n\ -"; - - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - <Para\n\ - <ParaLine\n\ - <ATbl 1>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - int i, j, num_rows, num_cols; - string row_ruling; - string col_ruling; - - num_rows = sm.numStates(); - num_cols = sm.numEvents() + 1; - - // -- Prolog - out << mif_prolog; - - // -- Table format (for each column) - for( i = 0; i < num_cols; i++ ) - { - out << tbl_fmt_before_col_num; - out << i; - out << tbl_fmt_after_col_num; - } - - // -- Spell out width of each column - - // -- FIXME: make following constants into parameters - const float total_table_width = 7.5; // -- Total page width = 7.5" (portrait mode) - const float min_col_width = 0.35; // -- Min col width (for legibility) - const float max_col_width = 0.75; // -- Max col width (for aesthetics) - float column_width; - - // -- Calculate column width and clamp it within a range - column_width = total_table_width / num_cols; - column_width = ((column_width < min_col_width) - ? min_col_width - : ((column_width > max_col_width) - ? max_col_width - : column_width)); - - out << tbl_fmt_before_num_cols; - out << num_cols; - for( i = 0; i < num_cols; i++ ) - { - out << tbl_fmt_each_col_width_begin << column_width << tbl_fmt_each_col_width_end; - } - - // -- Column headers - out << tbl_before_first_header1; - out << formatShorthand( sm.getShorthand() ); - out << " transitions"; - out << tbl_before_first_header2; - - out << tbl_before_each_header; - out << "State"; - out << tbl_after_each_header; - - for( i = 0; i < sm.numEvents(); i++ ) - { - out << tbl_before_each_rot_header; - out << formatShorthand( sm.getEvent(i).getShorthand() ); - out << tbl_after_each_header; - } - out << before_first_row; - - - // -- Body of table - for( i = 0; i < num_rows; i++ ) - { - // -- Each row - out << row_before_first_cell; - - // -- Figure out ruling - if (sm.getState(i).existPair("format")) { - row_ruling = formatCellRuling( sm.getState(i).lookupPair("format")); - } else { - row_ruling = ""; - } - - // -- First column = state - out << row_cell_before_ruling; - out << row_ruling; - out << row_cell_before_contents; - out << formatShorthand( sm.getState(i).getShorthand() ); - out << row_cell_after_contents; - - // -- One column for each event - for( j = 0; j < sm.numEvents(); j++ ) - { - const Transition* trans_ptr = sm.getTransPtr( i, j ); - - // -- Figure out ruling - if (sm.getEvent(j).existPair("format")) { - col_ruling = formatCellRuling(sm.getEvent(j).lookupPair("format")); - } else { - col_ruling = ""; - } - - out << row_cell_before_ruling; - out << row_ruling; - out << col_ruling; - - if( trans_ptr != NULL ) - { - string actions; - string nextState; - - // -- Get the actions - actions = formatShorthand( trans_ptr->getActionShorthands() ); - - // -- Get the next state - // FIXME: should compare index, not the string - if (trans_ptr->getNextStateShorthand() != - sm.getState(i).getShorthand() ) - { - nextState = formatShorthand( trans_ptr->getNextStateShorthand() ); - } else - { - nextState = ""; - } - - // -- Print out "actions/next-state" - out << row_cell_before_contents; - out << actions; - if ((nextState.length() != 0) && (actions.length() != 0)) { - out << "/"; - } - out << nextState; - out << row_cell_after_contents; - } - else - { - out << row_empty_cell; - } - - } - - out << row_after_last_cell; - } - - // -- Epilog - out << mif_epilog; - -} -/* -void printTBETableMIF(const StateMachine& sm, const Vector<Field>& fields, ostream& out) -{ - const string mif_prolog1 = -"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\ -<Tbls\n\ - <Tbl\n\ - <TblID 1>\n\ - <TblTag `Format A'>\n\ - <TblFormat\n\ -\n\ - <TblAlignment Center>\n\ -\n\ - # # <TblXColumnNum 0>\n\ - <TblXColumnRuling `Medium'>\n\ -\n\ - <TblLRuling `Medium'>\n\ - <TblRRuling `Medium'>\n\ - <TblTRuling `Medium'>\n\ - <TblBRuling `Medium'>\n\ -\n\ - <TblColumn\n\ - <TblColumnNum 0>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnH\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnH\n\ - <TblColumnBody\n\ - <PgfTag `CellBody'>\n\ - > # end of TblColumnBody\n\ - <TblColumnF\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - <TblColumn\n\ - <TblColumnNum 1>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnH\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnH\n\ - <TblColumnBody\n\ - <PgfTag `CellBody'>\n\ - > # end of TblColumnBody\n\ - <TblColumnF\n\ - <PgfTag `CellHeading'>\n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - > # end of TblFormat\n\ -\n\ - <TblNumColumns 2>\n\ - <TblColumnWidth 0.51\">\n\ - <TblColumnWidth 6.00\">\n\ - <TblTitle\n\ - <TblTitleContent\n\ - <Para\n\ - <PgfTag `TableTitle'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - <PgfNumString `TABLE 1. '>\n\ - <ParaLine\n\ - <Marker\n\ - <MType 9>\n\ - <MTypeName `Cross-Ref'>\n\ - <MCurrPage `1'>\n\ - > # end of Marker\n\ - <String `"; - - const string mif_prolog2 = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - <TblH\n\ - <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.44444\">\n\ - <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `Field'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - <Cell\n\ - <CellLRuling `Medium'>\n\ - <CellBRuling `Medium'>\n\ - <CellRRuling `Medium'>\n\ - <CellTRuling `Medium'>\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellHeading'>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - <ParaLine\n\ - <String `Description'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ - > # end of TblH\n\ -\n\ - <TblBody\n\ -"; - - const string row_before_state = -" <Row\n\ - <RowMaxHeight 14.0\">\n\ - <RowHeight 0.22222\">\n\ - <Cell\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <Pgf\n\ - <PgfAlignment Center>\n\ - <PgfFont \n\ - <FTag `'>\n\ - <FFamily `Times'>\n\ - <FVar `Regular'>\n\ - <FWeight `Regular'>\n\ - <FAngle `Regular'>\n\ - <FPostScriptName `Times-Roman'>\n\ - <FEncoding `FrameRoman'>\n\ - <FSize 11.0 pt>\n\ - <FUnderlining FNoUnderlining>\n\ - <FOverline No>\n\ - <FStrike No>\n\ - <FChangeBar No>\n\ - <FOutline No>\n\ - <FShadow No>\n\ - <FPairKern Yes>\n\ - <FTsume No>\n\ - <FCase FAsTyped>\n\ - <FPosition FNormal>\n\ - <FDX 0.0%>\n\ - <FDY 0.0%>\n\ - <FDW 0.0%>\n\ - <FStretch 100.0%>\n\ - <FLanguage USEnglish>\n\ - <FLocked No>\n\ - <FSeparation 0>\n\ - <FColor `Black'>\n\ - > # end of PgfFont\n\ - >\n\ - <ParaLine\n\ - <String `"; - - const string row_between_state_desc = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - <Cell\n\ - <CellContent\n\ - <Para\n\ - <PgfTag `CellBody'>\n\ - <ParaLine\n\ - <String `"; - - const string row_after_desc = - "'>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ -"; - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - <Para\n\ - <ParaLine\n\ - <ATbl 1>\n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - out << mif_prolog1; - out << sm.getShorthand(); - out << " TBE"; - out << mif_prolog2; - - for( int i = 0; i < fields.size(); i++ ) { - out << row_before_state; - out << formatShorthand(fields[i].getShorthand()); - out << row_between_state_desc; - out << fields[i].getDescription(); - out << row_after_desc; - } - - out << mif_epilog; -} -*/ -// -- -// -- Helper function to do some shorthand formatting (kludge before we -// -- get the tuple attributes into the state machine language. -// -- Current convention: -// -- - each `_' indicates a toggle between normal mode and superscript -// -- - each escaped (using `\') character indicates a letter formatted -// -- using the Symbol character set. \a = alpha, \b = beta, \c = chi etc. -// -- See the FrameMaker character sets manual in the Online Manuals. -// -- - a `!' indicates extra stuff at the end which can be ignored (used -// -- for determining cell ruling and so on) -// -- -string formatShorthand(const string shorthand) -{ - string munged_shorthand = ""; - bool mode_is_normal = true; - const string mif_superscript = "'> <Font <FPosition FSuperscript> <FLocked No> > <String `"; - const string mif_normal = "'> <Font <FPosition FNormal> <FLocked No> > <String `"; - const string mif_symbol = "'> <Font <FFamily `Symbol'> <FPostScriptName `Symbol'> <FEncoding `FrameRoman'> <FLocked No> > <String `"; - const string mif_times = "'> <Font <FFamily `Times'> <FPostScriptName `Times-Roman'> <FEncoding `FrameRoman'> <FLocked No> > <String `"; - - - // -- Walk over the string, processing superscript directives - for( unsigned int i = 0; i < shorthand.length(); i++ ) - { - if( shorthand[i] == '!' ) - { - // -- Reached logical end of shorthand name - break; - } - else if( shorthand[i] == '^' ) - { - // -- Process super/subscript formatting - - mode_is_normal = !mode_is_normal; - if( mode_is_normal ) - { - // -- Back to normal mode - munged_shorthand += mif_normal; - } - else - { - // -- Going to superscript mode - munged_shorthand += mif_superscript; - } - - } - else if( shorthand[i] == '\\' ) - { - // -- Process Symbol character set - if( (i + 1) < shorthand.length() ) - { - i++; // -- Proceed to next char. Yes I know that changing the loop var is ugly! - munged_shorthand += mif_symbol; - munged_shorthand += shorthand[i]; - munged_shorthand += mif_times; - } - else - { - // -- FIXME: Add line number info later - cerr << "Encountered a `\\` without anything following it!" << endl; - exit( -1 ); - } - - } - else - { - // -- Pass on un-munged - munged_shorthand += shorthand[i]; - } - - } // -- end for all characters in shorthand - - // -- Do any other munging - - // -- Return the formatted shorthand name - return munged_shorthand; -} - - -// -- -// -- Helper function to figure out where to put rules in the table (kludge before we -// -- get the tuple attributes into the shorthand machine language. -// -- Current convention: -// -- - a `!' in the shorthand indicates the beginning of ruling information -// -- - `b' => bottom of this row is ruled -// -- - `r' => right of this column is ruled -// -- -string formatCellRuling( const string shorthand) -{ - for( unsigned int i = 0; i < shorthand.length(); i++ ) - { - if( shorthand[i] == '!' ) - { - // -- OK, found beginning of ruling information - for( unsigned int j = i+1; j < shorthand.length(); j++ ) - { - if( shorthand[j] == 'b') - { - // -- Rule the bottom - return "<CellBRuling `Medium'>\n"; - } - else if( shorthand[j] == 'r') - { - // -- Rule the bottom - return "<CellRRuling `Medium'>\n"; - } - - } - - // -- No ruling directives recognized, return default ruling - return ""; - } - - } - - // -- No ruling information found, return default ruling - return ""; -} diff --git a/src/mem/slicc/generator/mif_gen.hh b/src/mem/slicc/generator/mif_gen.hh deleted file mode 100644 index 6da75f748..000000000 --- a/src/mem/slicc/generator/mif_gen.hh +++ /dev/null @@ -1,45 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id: mif_gen.hh,v 3.1 2001/12/12 01:00:35 milo Exp $ - * - */ - -#ifndef MIF_GEN_H -#define MIF_GEN_H - -#include "mem/slicc/symbols/StateMachine.hh" - -void printStateTableMIF(const StateMachine& sm, ostream& out); -void printEventTableMIF(const StateMachine& sm, ostream& out); -void printActionTableMIF(const StateMachine& sm, ostream& out); -void printTransitionTableMIF(const StateMachine& sm, ostream& out); - -#endif //MIF_GEN_H diff --git a/src/mem/slicc/main.cc b/src/mem/slicc/main.cc deleted file mode 100644 index 294925ee1..000000000 --- a/src/mem/slicc/main.cc +++ /dev/null @@ -1,246 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#include "mem/slicc/main.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/generator/mif_gen.hh" -#include "mem/slicc/generator/html_gen.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/ast/DeclListAST.hh" -#include "mem/slicc/symbols/Type.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/symbols/Event.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/slicc/symbols/Transition.hh" - -// -- Main conversion functions - -void printDotty(const StateMachine& sm, ostream& out); -void printTexTable(const StateMachine& sm, ostream& out); - -DeclListAST* g_decl_list_ptr; -DeclListAST* parse(string filename); - -int main(int argc, char *argv[]) -{ - cerr << "SLICC v0.3" << endl; - - if (argc < 5) { - cerr << " Usage: generator.exec <code path> <html path> <ident> <html direction> files ... " << endl; - exit(1); - } - - // The path we should place the generated code - string code_path(argv[1]); - code_path += "/"; - - // The path we should place the generated html - string html_path(argv[2]); - html_path += "/"; - - string ident(argv[3]); - - string html_generate(argv[4]); - - Vector<DeclListAST*> decl_list_vec; - - // Parse - cerr << "Parsing..." << endl; - for(int i=5; i<argc; i++) { - cerr << " " << argv[i] << endl; - DeclListAST* decl_list_ptr = parse(argv[i]); - decl_list_vec.insertAtBottom(decl_list_ptr); - } - - // Find machines - cerr << "Generator pass 1..." << endl; - int size = decl_list_vec.size(); - for(int i=0; i<size; i++) { - DeclListAST* decl_list_ptr = decl_list_vec[i]; - decl_list_ptr->findMachines(); - } - - // Generate Code - cerr << "Generator pass 2..." << endl; - for(int i=0; i<size; i++) { - DeclListAST* decl_list_ptr = decl_list_vec[i]; - decl_list_ptr->generate(); - delete decl_list_ptr; - } - - // Generate C/C++ files - cerr << "Writing C files..." << endl; - - { - // Generate the name of the protocol - ostringstream sstr; - sstr << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<<endl; - sstr << endl; - sstr << "#ifndef PROTOCOL_NAME_H" << endl; - sstr << "#define PROTOCOL_NAME_H" << endl; - sstr << endl; - sstr << "const char CURRENT_PROTOCOL[] = \""; - sstr << ident << "\";\n"; - sstr << "#endif // PROTOCOL_NAME_H" << endl; - conditionally_write_file(code_path + "/protocol_name.hh", sstr); - } - - g_sym_table.writeCFiles(code_path); - - // Generate HTML files - if (html_generate == "html") { - cerr << "Writing HTML files..." << endl; - g_sym_table.writeHTMLFiles(html_path); - } else if (html_generate == "no_html") { - cerr << "No HTML files generated" << endl; - } else { - cerr << "ERROR, unidentified html direction" << endl; - } - - cerr << "Done..." << endl; - - // Generate MIF files - cerr << "Writing MIF files..." << endl; - g_sym_table.writeMIFFiles(html_path); - - cerr << "Done..." << endl; - -} - /* - if(!strcmp(argv[2], "parse")) { - // Parse only - } else if(!strcmp(argv[2], "state")) { - printStateTableMIF(s, cout); - } else if(!strcmp( argv[2], "event")) { - printEventTableMIF(s, cout); - } else if(!strcmp( argv[2], "action")) { - printActionTableMIF(s, cout); - } else if(!strcmp( argv[2], "transition")) { - printTransitionTableMIF(s, cout); - } else if(!strcmp( argv[2], "tbe")) { - for(int i=0; i<s.numTypes(); i++) { - if (s.getType(i).getIdent() == "TBE") { - printTBETableMIF(s, s.getTypeFields(i), cout); - } - } - } else if(!strcmp( argv[2], "dot")) { - printDotty(s, cout); - } else if(!strcmp( argv[2], "latex")) { - printTexTable(s, cout); - } else if (!strcmp( argv[2], "murphi")) { - printMurphi(s, cout); - } else if (!strcmp( argv[2], "html")) { - printHTML(s); - } else if(!strcmp( argv[2], "code")) { - if (argc < 4) { - cerr << "Error: Wrong number of command line parameters!" << endl; - exit(1); - } - */ - - -void printDotty(const StateMachine& sm, ostream& out) -{ - out << "digraph " << sm.getIdent() << " {" << endl; - for(int i=0; i<sm.numTransitions(); i++) { - const Transition& t = sm.getTransition(i); - // Don't print ignored transitions - if ((t.getActionShorthands() != "--") && (t.getActionShorthands() != "z")) { - // if (t.getStateShorthand() != t.getNextStateShorthand()) { - out << " " << t.getStateShorthand() << " -> "; - out << t.getNextStateShorthand() << "[label=\""; - out << t.getEventShorthand() << "/" - << t.getActionShorthands() << "\"]" << endl; - } - } - out << "}" << endl; -} - -void printTexTable(const StateMachine& sm, ostream& out) -{ - const Transition* trans_ptr; - int stateIndex, eventIndex; - string actions; - string nextState; - - out << "%& latex" << endl; - out << "\\documentclass[12pt]{article}" << endl; - out << "\\usepackage{graphics}" << endl; - out << "\\begin{document}" << endl; - // out << "{\\large" << endl; - out << "\\begin{tabular}{|l||"; - for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) { - out << "l"; - } - out << "|} \\hline" << endl; - - for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) { - out << " & \\rotatebox{90}{"; - out << sm.getEvent(eventIndex).getShorthand(); - out << "}"; - } - out << "\\\\ \\hline \\hline" << endl; - - for(stateIndex=0; stateIndex < sm.numStates(); stateIndex++) { - out << sm.getState(stateIndex).getShorthand(); - for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) { - out << " & "; - trans_ptr = sm.getTransPtr(stateIndex, eventIndex); - if (trans_ptr == NULL) { - } else { - actions = trans_ptr->getActionShorthands(); - // FIXME: should compare index, not the string - if (trans_ptr->getNextStateShorthand() != - sm.getState(stateIndex).getShorthand() ) { - nextState = trans_ptr->getNextStateShorthand(); - } else { - nextState = ""; - } - - out << actions; - if ((nextState.length() != 0) && (actions.length() != 0)) { - out << "/"; - } - out << nextState; - } - } - out << "\\\\" << endl; - } - out << "\\hline" << endl; - out << "\\end{tabular}" << endl; - // out << "}" << endl; - out << "\\end{document}" << endl; -} - diff --git a/src/mem/slicc/main.hh b/src/mem/slicc/main.hh deleted file mode 100644 index a10dcca53..000000000 --- a/src/mem/slicc/main.hh +++ /dev/null @@ -1,48 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * main.hh - * - * Description: - * - * $Id: main.hh,v 3.2 2003/03/17 01:50:01 xu Exp $ - * - * */ - -#ifndef MAIN_H -#define MAIN_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclListAST.hh" -#include "mem/gems_common/Map.hh" - -extern DeclListAST* g_decl_list_ptr; - -#endif //MAIN_H diff --git a/src/mem/slicc/main.py b/src/mem/slicc/main.py new file mode 100644 index 000000000..f8efcc323 --- /dev/null +++ b/src/mem/slicc/main.py @@ -0,0 +1,100 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys + +from slicc.parser import SLICC + +usage="%prog [options] <files> ... " +version="%prog v0.4" +brief_copyright=''' +Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +Copyright (c) 2009 The Hewlett-Packard Development Company +All Rights Reserved. +''' + +def nprint(format, *args): + pass + +def eprint(format, *args): + if args: + format = format % args + + print >>sys.stderr, format + +def main(args=None): + import optparse + + parser = optparse.OptionParser(usage=usage, version=version, + description=brief_copyright) + parser.add_option("-d", "--debug", default=False, action="store_true", + help="Turn on PLY debugging") + parser.add_option("-C", "--code-path", default="generated", + help="Path where C++ code output code goes") + parser.add_option("-H", "--html-path", + help="Path where html output goes") + parser.add_option("-F", "--print-files", + help="Print files that SLICC will generate") + parser.add_option("-q", "--quiet", + help="don't print messages") + opts,files = parser.parse_args(args=args) + + if len(files) < 1: + parser.print_help() + sys.exit(2) + + output = nprint if opts.quiet else eprint + + output("SLICC v0.4") + slicc = SLICC(debug=opts.debug) + + output("Parsing...") + for filename in slicc.load(files, verbose=True): + output(" %s", filename) + + if opts.print_files: + for i in sorted(slicc.files()): + print ' %s' % i + else: + output("Generator pass 1...") + slicc.findMachines() + + output("Generator pass 2...") + slicc.generate() + + output("Generating C++ files...") + slicc.writeCodeFiles(opts.code_path) + + if opts.html_path: + nprint("Writing HTML files...") + slicc.writeHTMLFiles(opts.html_path) + + eprint("SLICC is Done.") + +if __name__ == "__main__": + main() diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py new file mode 100644 index 000000000..6c3f45629 --- /dev/null +++ b/src/mem/slicc/parser.py @@ -0,0 +1,667 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Nathan Binkert + +import os.path +import re +import sys + +from m5.util.grammar import Grammar, TokenError, ParseError + +import slicc.ast as ast +import slicc.util as util +from slicc.symbols import SymbolTable + +def read_slicc(sources): + if not isinstance(sources, (list,tuple)): + sources = [ sources ] + + for source in sources: + for sm_file in file(source, "r"): + sm_file = sm_file.strip() + if not sm_file: + continue + if sm_file.startswith("#"): + continue + yield sm_file + +class SLICC(Grammar): + def __init__(self, **kwargs): + super(SLICC, self).__init__(**kwargs) + self.decl_list_vec = [] + self.current_file = None + self.symtab = SymbolTable() + + def parse(self, filename): + self.current_file = filename + f = file(filename, 'r') + text = f.read() + try: + decl_list = super(SLICC, self).parse(text) + except (TokenError, ParseError), e: + sys.exit("%s: %s:%d" % (e, filename, e.token.lineno)) + self.decl_list_vec.append(decl_list) + self.current_file = None + + def _load(self, *filenames): + filenames = list(filenames) + while filenames: + f = filenames.pop(0) + if isinstance(f, (list, tuple)): + filenames[0:0] = list(f) + continue + + yield f + if f.endswith(".slicc"): + dirname,basename = os.path.split(f) + filenames[0:0] = [ os.path.join(dirname, x) \ + for x in read_slicc(f)] + else: + assert f.endswith(".sm") + self.parse(f) + + def load(self, *filenames, **kwargs): + verbose = kwargs.pop("verbose", False) + if kwargs: + raise TypeError + + gen = self._load(*filenames) + if verbose: + return gen + else: + # Run out the generator if we don't want the verbosity + for foo in gen: + pass + + def findMachines(self): + for decl_list in self.decl_list_vec: + decl_list.findMachines() + + def generate(self): + for decl_list in self.decl_list_vec: + decl_list.generate() + + def writeCodeFiles(self, code_path): + util.makeDir(code_path) + self.symtab.writeCodeFiles(code_path) + + def writeHTMLFiles(self, code_path): + util.makeDir(code_path) + self.symtab.writeHTMLFiles(code_path) + + def files(self): + f = set([ + 'ControllerFactory.cc', + 'ControllerFactory.hh', + 'MachineType.cc', + 'MachineType.hh', + 'Types.hh' ]) + + for decl_list in self.decl_list_vec: + f |= decl_list.files() + + return f + + t_ignore = '\t ' + + # C or C++ comment (ignore) + def t_c_comment(self, t): + r'/\*(.|\n)*?\*/' + t.lexer.lineno += t.value.count('\n') + + def t_cpp_comment(self, t): + r'//.*' + + # Define a rule so we can track line numbers + def t_newline(self, t): + r'\n+' + t.lexer.lineno += len(t.value) + + reserved = { + 'global' : 'GLOBAL', + 'machine' : 'MACHINE', + 'in_port' : 'IN_PORT', + 'out_port' : 'OUT_PORT', + 'action' : 'ACTION', + 'transition' : 'TRANS', + 'structure' : 'STRUCT', + 'external_type' : 'EXTERN_TYPE', + 'enumeration' : 'ENUM', + 'peek' : 'PEEK', + 'enqueue' : 'ENQUEUE', + 'copy_head' : 'COPY_HEAD', + 'check_allocate' : 'CHECK_ALLOCATE', + 'check_stop_slots' : 'CHECK_STOP_SLOTS', + 'if' : 'IF', + 'else' : 'ELSE', + 'return' : 'RETURN', + 'THIS' : 'THIS', + 'CHIP' : 'CHIP', + 'void' : 'VOID', + 'new' : 'NEW', + } + + literals = ':[]{}(),=' + + tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE', + 'LEFTSHIFT', 'RIGHTSHIFT', + 'NOT', 'AND', 'OR', + 'PLUS', 'DASH', 'STAR', 'SLASH', + 'DOUBLE_COLON', 'SEMI', + 'ASSIGN', 'DOT', + 'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ] + tokens += reserved.values() + + t_EQ = r'==' + t_NE = r'!=' + t_LT = r'<' + t_GT = r'>' + t_LE = r'<=' + t_GE = r'>=' + t_LEFTSHIFT = r'<<' + t_RIGHTSHIFT = r'>>' + t_NOT = r'!' + t_AND = r'&&' + t_OR = r'\|\|' + t_PLUS = r'\+' + t_DASH = r'-' + t_STAR = r'\*' + t_SLASH = r'/' + t_DOUBLE_COLON = r'::' + t_SEMI = r';' + t_ASSIGN = r':=' + t_DOT = r'\.' + + precedence = ( + ('left', 'AND', 'OR'), + ('left', 'EQ', 'NE'), + ('left', 'LT', 'GT', 'LE', 'GE'), + ('left', 'RIGHTSHIFT', 'LEFTSHIFT'), + ('left', 'PLUS', 'DASH'), + ('left', 'STAR', 'SLASH'), + ('right', 'NOT', 'UMINUS'), + ) + + def t_IDENT(self, t): + r'[a-zA-Z_][a-zA-Z_0-9]*' + if t.value == 'true': + t.type = 'LIT_BOOL' + t.value = True + return t + + if t.value == 'false': + t.type = 'LIT_BOOL' + t.value = False + return t + + # Check for reserved words + t.type = self.reserved.get(t.value, 'IDENT') + return t + + def t_FLOATNUMBER(self, t): + '[0-9]+[.][0-9]+' + try: + t.value = float(t.value) + except ValueError: + raise TokenError("Illegal float", t) + return t + + def t_NUMBER(self, t): + r'[0-9]+' + try: + t.value = int(t.value) + except ValueError: + raise TokenError("Illegal number", t) + return t + + def t_STRING1(self, t): + r'\"[^"\n]*\"' + t.type = 'STRING' + t.value = t.value[1:-1] + return t + + def t_STRING2(self, t): + r"\'[^'\n]*\'" + t.type = 'STRING' + t.value = t.value[1:-1] + return t + + def p_file(self, p): + "file : decls" + p[0] = p[1] + + def p_empty(self, p): + "empty :" + + def p_decls(self, p): + "decls : declsx" + p[0] = ast.DeclListAST(self, p[1]) + + def p_declsx__list(self, p): + "declsx : decl declsx" + p[0] = [ p[1] ] + p[2] + + def p_declsx__none(self, p): + "declsx : empty" + p[0] = [] + + def p_decl__machine(self, p): + "decl : MACHINE '(' ident pairs ')' ':' params '{' decls '}'" + p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9]) + + def p_decl__action(self, p): + "decl : ACTION '(' ident pairs ')' statements" + p[0] = ast.ActionDeclAST(self, p[3], p[4], p[6]) + + def p_decl__in_port(self, p): + "decl : IN_PORT '(' ident ',' type ',' var pairs ')' statements" + p[0] = ast.InPortDeclAST(self, p[3], p[5], p[7], p[8], p[10]) + + def p_decl__out_port(self, p): + "decl : OUT_PORT '(' ident ',' type ',' var pairs ')' SEMI" + p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8]) + + def p_decl__trans0(self, p): + "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents" + p[0] = ast.TransitionDeclAST(self, p[3], p[5], p[7], p[8], p[10]) + + def p_decl__trans1(self, p): + "decl : TRANS '(' idents ',' idents pairs ')' idents" + p[0] = ast.TransitionDeclAST(self, p[3], p[5], None, p[6], p[8]) + + def p_decl__extern0(self, p): + "decl : EXTERN_TYPE '(' type pairs ')' SEMI" + p[4]["external"] = "yes" + p[0] = ast.TypeDeclAST(self, p[3], p[4], []) + + def p_decl__extern1(self, p): + "decl : EXTERN_TYPE '(' type pairs ')' '{' type_methods '}'" + p[4]["external"] = "yes" + p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) + + def p_decl__global(self, p): + "decl : GLOBAL '(' type pairs ')' '{' type_members '}'" + p[4]["global"] = "yes" + p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) + + def p_decl__struct(self, p): + "decl : STRUCT '(' type pairs ')' '{' type_members '}'" + p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) + + def p_decl__enum(self, p): + "decl : ENUM '(' type pairs ')' '{' type_enums '}'" + p[4]["enumeration"] = "yes" + p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7]) + + def p_decl__object(self, p): + "decl : type ident pairs SEMI" + p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3]) + + def p_decl__func_decl(self, p): + """decl : void ident '(' params ')' pairs SEMI + | type ident '(' params ')' pairs SEMI""" + p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None) + + def p_decl__func_def(self, p): + """decl : void ident '(' params ')' pairs statements + | type ident '(' params ')' pairs statements""" + p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7]) + + # Type fields + def p_type_members__list(self, p): + "type_members : type_member type_members" + p[0] = [ p[1] ] + p[2] + + def p_type_members__empty(self, p): + "type_members : empty" + p[0] = [] + + def p_type_member__1(self, p): + "type_member : type ident pairs SEMI" + p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], p[3], None) + + def p_type_member__2(self, p): + "type_member : type ident ASSIGN expr SEMI" + p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], + ast.PairListAST(self), p[4]) + + # Methods + def p_type_methods__list(self, p): + "type_methods : type_method type_methods" + p[0] = [ p[1] ] + p[2] + + def p_type_methods(self, p): + "type_methods : empty" + p[0] = [] + + def p_type_method(self, p): + "type_method : type_or_void ident '(' types ')' pairs SEMI" + p[0] = ast.TypeFieldMethodAST(self, p[1], p[2], p[4], p[6]) + + # Enum fields + def p_type_enums__list(self, p): + "type_enums : type_enum type_enums" + p[0] = [ p[1] ] + p[2] + + def p_type_enums__empty(self, p): + "type_enums : empty" + p[0] = [] + + def p_type_enum(self, p): + "type_enum : ident pairs SEMI" + p[0] = ast.TypeFieldEnumAST(self, p[1], p[2]) + + # Type + def p_types__multiple(self, p): + "types : type ',' types" + p[0] = [ p[1] ] + p[3] + + def p_types__one(self, p): + "types : type" + p[0] = [ p[1] ] + + def p_types__empty(self, p): + "types : empty" + p[0] = [] + + def p_type(self, p): + "type : ident" + p[0] = ast.TypeAST(self, p[1]) + + def p_void(self, p): + "void : VOID" + p[0] = ast.TypeAST(self, p[1]) + + def p_type_or_void(self, p): + """type_or_void : type + | void""" + p[0] = p[1] + + # Formal Param + def p_params__many(self, p): + "params : param ',' params" + p[0] = [ p[1] ] + p[3] + + def p_params__one(self, p): + "params : param" + p[0] = [ p[1] ] + + def p_params__none(self, p): + "params : empty" + p[0] = [] + + def p_param(self, p): + "param : type ident" + p[0] = ast.FormalParamAST(self, p[1], p[2]) + + # Idents and lists + def p_idents__braced(self, p): + "idents : '{' identx '}'" + p[0] = p[2] + + def p_idents__bare(self, p): + "idents : ident" + p[0] = [ p[1] ] + + def p_identx__multiple_1(self, p): + """identx : ident SEMI identx + | ident ',' identx""" + p[0] = [ p[1] ] + p[3] + + def p_identx__multiple_2(self, p): + "identx : ident identx" + p[0] = [ p[1] ] + p[2] + + def p_identx__single(self, p): + "identx : empty" + p[0] = [ ] + + def p_ident(self, p): + "ident : IDENT" + p[0] = p[1] + + # Pair and pair lists + def p_pairs__list(self, p): + "pairs : ',' pairsx" + p[0] = p[2] + + def p_pairs__empty(self, p): + "pairs : empty" + p[0] = ast.PairListAST(self) + + def p_pairsx__many(self, p): + "pairsx : pair ',' pairsx" + p[0] = p[3] + p[0].addPair(p[1]) + + def p_pairsx__one(self, p): + "pairsx : pair" + p[0] = ast.PairListAST(self) + p[0].addPair(p[1]) + + def p_pair__assign(self, p): + """pair : ident '=' STRING + | ident '=' ident""" + p[0] = ast.PairAST(self, p[1], p[3]) + + def p_pair__literal(self, p): + "pair : STRING" + p[0] = ast.PairAST(self, "short", p[1]) + + # Below are the rules for action descriptions + def p_statements__inner(self, p): + "statements : '{' statements_inner '}'" + p[0] = ast.StatementListAST(self, p[2]) + + def p_statements__none(self, p): + "statements : '{' '}'" + p[0] = ast.StatementListAST(self, []) + + def p_statements_inner__many(self, p): + "statements_inner : statement statements_inner" + p[0] = [ p[1] ] + p[2] + + def p_statements_inner__one(self, p): + "statements_inner : statement" + p[0] = [ p[1] ] + + def p_exprs__multiple(self, p): + "exprs : expr ',' exprs" + p[0] = [ p[1] ] + p[3] + + def p_exprs__one(self, p): + "exprs : expr" + p[0] = [ p[1] ] + + def p_exprs__empty(self, p): + "exprs : empty""" + p[0] = [] + + def p_statement__expression(self, p): + "statement : expr SEMI" + p[0] = ast.ExprStatementAST(self, p[1]) + + def p_statement__assign(self, p): + "statement : expr ASSIGN expr SEMI" + p[0] = ast.AssignStatementAST(self, p[1], p[3]) + + def p_statement__enqueue(self, p): + "statement : ENQUEUE '(' var ',' type pairs ')' statements" + p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[6], p[8]) + + def p_statement__peek(self, p): + "statement : PEEK '(' var ',' type ')' statements" + p[0] = ast.PeekStatementAST(self, p[3], p[5], p[7], "peek") + + def p_statement__copy_head(self, p): + "statement : COPY_HEAD '(' var ',' var pairs ')' SEMI" + p[0] = ast.CopyHeadStatementAST(self, p[3], p[5], p[6]) + + def p_statement__check_allocate(self, p): + "statement : CHECK_ALLOCATE '(' var ')' SEMI" + p[0] = ast.CheckAllocateStatementAST(self, p[3]) + + def p_statement__check_stop(self, p): + "statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI" + p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7]) + + def p_statement__return(self, p): + "statement : RETURN expr SEMI" + p[0] = ast.ReturnStatementAST(self, p[2]) + + def p_statement__if(self, p): + "statement : if_statement" + p[0] = p[1] + + def p_if_statement__if(self, p): + "if_statement : IF '(' expr ')' statements" + p[0] = ast.IfStatementAST(self, p[3], p[5], None) + + def p_if_statement__if_else(self, p): + "if_statement : IF '(' expr ')' statements ELSE statements" + p[0] = ast.IfStatementAST(self, p[3], p[5], p[7]) + + def p_statement__if_else_if(self, p): + "if_statement : IF '(' expr ')' statements ELSE if_statement" + p[0] = ast.IfStatementAST(self, p[3], p[5], + ast.StatementListAST(self, p[7])) + + def p_expr__var(self, p): + "aexpr : var" + p[0] = p[1] + + def p_expr__literal(self, p): + "aexpr : literal" + p[0] = p[1] + + def p_expr__enumeration(self, p): + "aexpr : enumeration" + p[0] = p[1] + + def p_expr__func_call(self, p): + "aexpr : ident '(' exprs ')'" + p[0] = ast.FuncCallExprAST(self, p[1], p[3]) + + def p_expr__new(self, p): + "aexpr : NEW type" + p[0] = ast.NewExprAST(self, p[2]) + + # globally access a local chip component and call a method + def p_expr__local_chip_method(self, p): + "aexpr : THIS DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'" + p[0] = ast.LocalChipMethodAST(self, p[3], p[5], p[8], p[10], p[12]) + + # globally access a local chip component and access a data member + def p_expr__local_chip_member(self, p): + "aexpr : THIS DOT var '[' expr ']' DOT var DOT field" + p[0] = ast.LocalChipMemberAST(self, p[3], p[5], p[8], p[10]) + + # globally access a specified chip component and call a method + def p_expr__specified_chip_method(self, p): + "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'" + p[0] = ast.SpecifiedChipMethodAST(self, p[3], p[6], p[8], p[11], p[13], + p[15]) + + # globally access a specified chip component and access a data member + def p_expr__specified_chip_member(self, p): + "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field" + p[0] = ast.SpecifiedChipMemberAST(self, p[3], p[6], p[8], p[11], p[13]) + + def p_expr__member(self, p): + "aexpr : aexpr DOT ident" + p[0] = ast.MemberExprAST(self, p[1], p[3]) + + def p_expr__member_method_call(self, p): + "aexpr : aexpr DOT ident '(' exprs ')'" + p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5]) + + def p_expr__member_method_call_lookup(self, p): + "aexpr : aexpr '[' exprs ']'" + p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3]) + + def p_expr__class_method_call(self, p): + "aexpr : type DOUBLE_COLON ident '(' exprs ')'" + p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5]) + + def p_expr__aexpr(self, p): + "expr : aexpr" + p[0] = p[1] + + def p_expr__binary_op(self, p): + """expr : expr STAR expr + | expr SLASH expr + | expr PLUS expr + | expr DASH expr + | expr LT expr + | expr GT expr + | expr LE expr + | expr GE expr + | expr EQ expr + | expr NE expr + | expr AND expr + | expr OR expr + | expr RIGHTSHIFT expr + | expr LEFTSHIFT expr""" + p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3]) + + # FIXME - unary not + def p_expr__unary_op(self, p): + """expr : NOT expr + | DASH expr %prec UMINUS""" + p[0] = PrefixOperatorExpr(p[1], p[2]) + + def p_expr__parens(self, p): + "aexpr : '(' expr ')'" + p[0] = p[2] + + def p_literal__string(self, p): + "literal : STRING" + p[0] = ast.LiteralExprAST(self, p[1], "string") + + def p_literal__number(self, p): + "literal : NUMBER" + p[0] = ast.LiteralExprAST(self, p[1], "int") + + def p_literal__float(self, p): + "literal : FLOATNUMBER" + p[0] = ast.LiteralExprAST(self, p[1], "int") + + def p_literal__bool(self, p): + "literal : LIT_BOOL" + p[0] = ast.LiteralExprAST(self, p[1], "bool") + + def p_enumeration(self, p): + "enumeration : ident ':' ident" + p[0] = ast.EnumExprAST(self, ast.TypeAST(self, p[1]), p[3]) + + def p_var(self, p): + "var : ident" + p[0] = ast.VarExprAST(self, p[1]) + + def p_field(self, p): + "field : ident" + p[0] = p[1] diff --git a/src/mem/slicc/parser/lexer.ll b/src/mem/slicc/parser/lexer.ll deleted file mode 100644 index b2d36855b..000000000 --- a/src/mem/slicc/parser/lexer.ll +++ /dev/null @@ -1,125 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -%{ - -#include <assert.h> -#include "mem/slicc/ast/ASTs.hh" -#include "parser.hh" -#include <string> - -extern "C" int yylex(); -extern "C" void yyerror(); -extern "C" int yywrap() -{ - return 1; -} - -%} -%x CMNT -%x IMBEDED -%% - -[\t ]+ /* Ignore whitespace */ -[\n] { g_line_number++; } -"//".*[\n] { g_line_number++; } /* C++ style comments */ - -"/*" BEGIN CMNT; -<CMNT>. ; -<CMNT>\n { g_line_number++; } -<CMNT>"*/" { BEGIN INITIAL; } - -true { yylval.str_ptr = new string(yytext); return LIT_BOOL; } -false { yylval.str_ptr = new string(yytext); return LIT_BOOL; } -global { return GLOBAL_DECL; } -machine { return MACHINE_DECL; } -in_port { return IN_PORT_DECL; } -out_port { return OUT_PORT_DECL; } -action { return ACTION_DECL; } -transition { return TRANSITION_DECL; } -structure { return STRUCT_DECL; } -external_type { return EXTERN_TYPE_DECL; } -enumeration { return ENUM_DECL; } -peek { return PEEK; } -enqueue { return ENQUEUE; } -copy_head { return COPY_HEAD; } -check_allocate { return CHECK_ALLOCATE; } -check_stop_slots { return CHECK_STOP_SLOTS; } -if { return IF; } -else { return ELSE; } -return { return RETURN; } -THIS { return THIS; } -CHIP { return CHIP; } -void { yylval.str_ptr = new string(yytext); return VOID; } -new { return NEW; } - -== { yylval.str_ptr = new string(yytext); return EQ; } -!= { yylval.str_ptr = new string(yytext); return NE; } -[<] { yylval.str_ptr = new string(yytext); return '<'; } -[>] { yylval.str_ptr = new string(yytext); return '>'; } -[<][<] { yylval.str_ptr = new string(yytext); return LEFTSHIFT; } -[>][>] { yylval.str_ptr = new string(yytext); return RIGHTSHIFT; } -[<][=] { yylval.str_ptr = new string(yytext); return LE; } -[>][=] { yylval.str_ptr = new string(yytext); return GE; } -[!] { yylval.str_ptr = new string(yytext); return NOT; } -[&][&] { yylval.str_ptr = new string(yytext); return AND; } -[|][|] { yylval.str_ptr = new string(yytext); return OR; } -[+] { yylval.str_ptr = new string(yytext); return PLUS; } -[-] { yylval.str_ptr = new string(yytext); return DASH; } -[*] { yylval.str_ptr = new string(yytext); return STAR; } -[/] { yylval.str_ptr = new string(yytext); return SLASH; } -:: { return DOUBLE_COLON; } -[:] { return ':'; } -[;] { return SEMICOLON; } -[[] { return '['; } -[]] { return ']'; } -[{] { return '{'; } -[}] { return '}'; } -[(] { return '('; } -[)] { return ')'; } -[,] { return ','; } -[=] { return '='; } -:= { return ASSIGN; } -[.] { return DOT; } - -[0-9]*[.][0-9]* { yylval.str_ptr = new string(yytext); return FLOATNUMBER; } -[0-9]* { yylval.str_ptr = new string(yytext); return NUMBER; } - -[a-zA-Z_][a-zA-Z_0-9]{0,50} { yylval.str_ptr = new string(yytext); return IDENT; } -\"[^"\n]*\" { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; } -\'[^'\n]*\' { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; } - -. { return OTHER; } /* Need so that we handle all characters */ - -%% - diff --git a/src/mem/slicc/parser/parser.py b/src/mem/slicc/parser/parser.py deleted file mode 100644 index 7fecfd273..000000000 --- a/src/mem/slicc/parser/parser.py +++ /dev/null @@ -1,563 +0,0 @@ -# Copyright (c) 2009 The Hewlett-Packard Development Company -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Nathan Binkert - -from ply import lex, yacc -import re - -t_ignore = '\t ' - -# C or C++ comment (ignore) -def t_c_comment(t): - r'/\*(.|\n)*?\*/' - t.lexer.lineno += t.value.count('\n') - -def t_cpp_comment(t): - r'//.*' - pass - -# Define a rule so we can track line numbers -def t_newline(t): - r'\n+' - t.lexer.lineno += len(t.value) - -reserved = { - 'global' : 'GLOBAL', - 'machine' : 'MACHINE', - 'in_port' : 'IN_PORT', - 'out_port' : 'OUT_PORT', - 'action' : 'ACTION', - 'transition' : 'TRANS', - 'structure' : 'STRUCT', - 'external_type' : 'EXTERN_TYPE', - 'enumeration' : 'ENUM', - 'peek' : 'PEEK', - 'enqueue' : 'ENQUEUE', - 'copy_head' : 'COPY_HEAD', - 'check_allocate' : 'CHECK_ALLOCATE', - 'check_stop_slots' : 'CHECK_STOP_SLOTS', - 'if' : 'IF', - 'else' : 'ELSE', - 'return' : 'RETURN', - 'THIS' : 'THIS', - 'CHIP' : 'CHIP', - 'void' : 'VOID', - 'new' : 'NEW', -} - -literals = ':[]{}(),=' - -tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE', - 'LEFTSHIFT', 'RIGHTSHIFT', - 'NOT', 'AND', 'OR', - 'PLUS', 'DASH', 'STAR', 'SLASH', - 'DOUBLE_COLON', 'SEMICOLON', - 'ASSIGN', 'DOT', - 'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ] -tokens += reserved.values() - -t_EQ = r'==' -t_NE = r'!=' -t_LT = r'<' -t_GT = r'>' -t_LE = r'<=' -t_GE = r'>=' -t_LEFTSHIFT = r'<<' -t_RIGHTSHIFT = r'>>' -t_NOT = r'!' -t_AND = r'&&' -t_OR = r'\|\|' -t_PLUS = r'\+' -t_DASH = r'-' -t_STAR = r'\*' -t_SLASH = r'/' -t_DOUBLE_COLON = r'::' -t_SEMICOLON = r';' -t_ASSIGN = r':=' -t_DOT = r'\.' - -class TokenError(Exception): - def __init__(self, msg, t): - super(TokenError, self).__init__(msg) - self.token = t - -class ParseError(Exception): - def __init__(self, msg, t): - super(ParseError, self).__init__(msg) - self.token = t - -def t_error(t): - raise TokenError("Illegal character", t) - -def t_IDENT(t): - r'[a-zA-Z_][a-zA-Z_0-9]*' - if t.value == 'true': - t.type = 'LIT_BOOL' - t.value = True - return t - - if t.value == 'false': - t.type = 'LIT_BOOL' - t.value = False - return t - - if t.value.startswith('LATENCY_'): - t.type = 'LATENCY' - return t - - t.type = reserved.get(t.value, 'IDENT') # Check for reserved words - return t - -def t_FLOATNUMBER(t): - '[0-9]+[.][0-9]+' - try: - t.value = float(t.value) - except ValueError: - raise TokenError("Illegal float", t) - return t - -def t_NUMBER(t): - r'[0-9]+' - try: - t.value = int(t.value) - except ValueError: - raise TokenError("Illegal number", t) - return t - -def t_STRING1(t): - r'\"[^"\n]*\"' - t.type = 'STRING' - return t - -def t_STRING2(t): - r"\'[^'\n]*\'" - t.type = 'STRING' - return t - - -def p_file(p): - "file : decl_l" - p[0] = [ x for x in p[1] if x is not None ] - -def p_error(t): - raise ParseError("Syntax error", t) - -def p_empty(p): - "empty :" - pass - -def p_decl_l(p): - "decl_l : decls" - p[0] = p[1] - -def p_decls(p): - """decls : decl decls - | empty""" - if len(p) == 3: - p[0] = [ p[1] ] + p[2] - elif len(p) == 2: - p[0] = [] - -def p_decl(p): - """decl : d_machine - | d_action - | d_in_port - | d_out_port - | t_trans - | d_extern - | d_global - | d_struct - | d_enum - | d_object - | d_func_decl - | d_func_def""" - p[0] = p[1] - -def p_d_machine(p): - """d_machine : MACHINE '(' ident pair_l ')' ':' param_l '{' decl_l '}'""" - - if len(p) == 9: - decl_l = p[7] - elif len(p) == 11: - decl_l = p[9] - decls = [ x for x in decl_l if x is not None ] - p[0] = Machine(p[3], decls) - -def p_d_action(p): - "d_action : ACTION '(' ident pair_l ')' statement_l" - p[0] = Action(p[3]) - -def p_d_in_port(p): - "d_in_port : IN_PORT '(' ident ',' type ',' var pair_l ')' statement_l" - p[0] = InPort(p[3]) - -def p_d_out_port(p): - "d_out_port : OUT_PORT '(' ident ',' type ',' var pair_l ')' SEMICOLON" - p[0] = OutPort(p[3]) - -def p_t_trans(p): - """t_trans : TRANS '(' ident_l ',' ident_l ',' ident pair_l ')' ident_l - | TRANS '(' ident_l ',' ident_l pair_l ')' ident_l""" - p[0] = Transition("transition") - -def p_d_extern(p): - """d_extern : EXTERN_TYPE '(' type pair_l ')' SEMICOLON - | EXTERN_TYPE '(' type pair_l ')' '{' type_methods '}'""" - p[0] = Extern(p[3]) - -def p_d_global(p): - "d_global : GLOBAL '(' type pair_l ')' '{' type_members '}'" - p[0] = Global(p[3]) - -def p_d_struct(p): - "d_struct : STRUCT '(' type pair_l ')' '{' type_members '}'" - p[0] = Struct(p[3]) - -def p_d_enum(p): - "d_enum : ENUM '(' type pair_l ')' '{' type_enums '}'" - p[0] = Enum(p[3]) - -def p_d_object(p): - "d_object : type ident pair_l SEMICOLON" - p[0] = Object(p[2]) - -def p_d_func_decl(p): - """d_func_decl : void ident '(' param_l ')' pair_l SEMICOLON - | type ident '(' param_l ')' pair_l SEMICOLON""" - pass - -def p_d_func_def(p): - """d_func_def : void ident '(' param_l ')' pair_l statement_l - | type ident '(' param_l ')' pair_l statement_l""" - p[0] = Function(p[2]) - -# Type fields -def p_type_members(p): - """type_members : type_member type_members - | empty""" - pass - -def p_type_member(p): - """type_member : type ident pair_l SEMICOLON - | type ident ASSIGN expr SEMICOLON""" - pass - -# Methods -def p_type_methods(p): - """type_methods : type_method type_methods - | empty""" - pass - -def p_type_method(p): - "type_method : type_or_void ident '(' type_l ')' pair_l SEMICOLON" - pass - -# Enum fields -def p_type_enums(p): - """type_enums : type_enum type_enums - | empty""" - pass - -def p_type_enum(p): - "type_enum : ident pair_l SEMICOLON" - pass - -# Type -def p_type_l(p): - """type_l : types - | empty""" - pass - -def p_types(p): - """types : type ',' types - | type""" - pass - -def p_type(p): - "type : ident" - p[0] = p[1] - -def p_void(p): - "void : VOID" - p[0] = None - -def p_type_or_void(p): - """type_or_void : type - | void""" - p[0] = p[1] - -# Formal Param -def p_param_l(p): - """param_l : params - | empty""" - pass - -def p_params(p): - """params : param ',' params - | param""" - pass - -def p_param(p): - "param : type ident" - pass - -# Idents and lists -def p_ident(p): - "ident : IDENT" - p[0] = p[1] - -def p_ident_l(p): - """ident_l : '{' idents '}' - | ident""" - p[0] = p[1] - -def p_idents(p): - """idents : ident SEMICOLON idents - | ident ',' idents - | ident idents - | empty""" - pass - -# Pair and pair lists -def p_pair_l(p): - """pair_l : ',' pairs - | empty""" - if len(p) == 3: - p[0] = p[2] - elif len(p) == 2: - p[0] = None - -def p_pairs(p): - """pairs : pair ',' pairs - | pair""" - if len(p) == 4: - p[3].append(p[1]) - p[0] = p[3] - elif len(p) == 2: - p[0] = [ p[1] ] - -def p_pair(p): - """pair : ident '=' STRING - | ident '=' ident - | STRING""" - if len(p) == 4: - p[0] = p[1], p[3] - elif len(p) == 2: - p[0] = "short", p[1] - -# Below are the rules for action descriptions -def p_statement_l(p): - "statement_l : '{' statements '}'" - pass - -def p_statements(p): - """statements : statement statements - | empty""" - pass - -def p_expr_l(p): - """expr_l : expr ',' expr_l - | expr - | empty""" - pass - -def p_statement(p): - """statement : expr SEMICOLON - | expr ASSIGN expr SEMICOLON - | ENQUEUE '(' var ',' type pair_l ')' statement_l - | PEEK '(' var ',' type ')' statement_l - | COPY_HEAD '(' var ',' var pair_l ')' SEMICOLON - | CHECK_ALLOCATE '(' var ')' SEMICOLON - | CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMICOLON - | if_statement - | RETURN expr SEMICOLON""" - pass - -def p_if_statement(p): - """if_statement : IF '(' expr ')' statement_l ELSE statement_l - | IF '(' expr ')' statement_l - | IF '(' expr ')' statement_l ELSE if_statement""" - pass - -def p_expr(p): - """expr : var - | literal - | enumeration - | ident '(' expr_l ')' - | NEW type - | THIS DOT var '[' expr ']' DOT var DOT ident '(' expr_l ')' - | THIS DOT var '[' expr ']' DOT var DOT ident - | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' expr_l ')' - | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident - | expr DOT ident - | expr DOT ident '(' expr_l ')' - | type DOUBLE_COLON ident '(' expr_l ')' - | expr '[' expr_l ']' - | expr STAR expr - | expr SLASH expr - | expr PLUS expr - | expr DASH expr - | expr LT expr - | expr GT expr - | expr LE expr - | expr GE expr - | expr EQ expr - | expr NE expr - | expr AND expr - | expr OR expr - | NOT expr - | expr RIGHTSHIFT expr - | expr LEFTSHIFT expr - | '(' expr ')'""" - pass - -def p_literal(p): - """literal : STRING - | NUMBER - | FLOATNUMBER - | LIT_BOOL""" - pass - -def p_enumeration(p): - "enumeration : ident ':' ident" - pass - -def p_var(p): - "var : ident" - pass - -lex.lex() -yacc.yacc(write_tables=0) - -slicc_generated_cc = set([ - 'ControllerFactory.cc', - 'MachineType.cc']) - -slicc_generated_hh = set([ - 'ControllerFactory.hh', - 'MachineType.hh', - 'Types.hh', - 'protocol_name.hh' ]) - -class Machine(object): - def __init__(self, name, decls): - self.name = name - self.decls = decls - - def add(self, hh, cc): - hh.add('%s_Controller.hh' % self.name) - hh.add('%s_Profiler.hh' % self.name) - - cc.add('%s_Controller.cc' % self.name) - cc.add('%s_Profiler.cc' % self.name) - cc.add('%s_Transitions.cc' % self.name) - cc.add('%s_Wakeup.cc' % self.name) - - for decl in self.decls: - decl.add(hh, cc, self.name) - -class Declaration(object): - hh = False - cc = False - def __init__(self, name): - self.name = name - - def add(self, hh, cc, name=None): - #print '>>>', type(self).__name__, self.name - if name: - name += '_' - else: - name = "" - if self.hh: - hh.add('%s%s.hh' % (name, self.name)) - if self.cc: - cc.add('%s%s.cc' % (name, self.name)) - -class Action(Declaration): pass -class InPort(Declaration): pass -class OutPort(Declaration): pass -class Transition(Declaration): pass -class Extern(Declaration): pass -class Global(Declaration): - hh = True - cc = True -class Struct(Declaration): - hh = True - cc = True -class Enum(Declaration): - hh = True - cc = True -class Object(Declaration): pass -class Function(Declaration): - cc = True - -def read_slicc(sources): - if not isinstance(sources, (list,tuple)): - sources = [ sources ] - - sm_files = [] - for source in sources: - for sm_file in file(source, "r"): - sm_file = sm_file.strip() - if not sm_file: - continue - if sm_file.startswith("#"): - continue - sm_files.append(sm_file) - - return sm_files - -def scan(filenames): - hh = slicc_generated_hh.copy() - cc = slicc_generated_cc.copy() - - for filename in filenames: - lex.lexer.lineno = 1 - try: - print "parsing ",filename - results = yacc.parse(file(filename, 'r').read()) - except (TokenError, ParseError), e: - sys.exit("%s: %s:%d" % (e, filename, e.token.lineno)) - - for result in results: - result.add(hh, cc) - - return list(hh), list(cc) - -if __name__ == '__main__': - import sys - - hh, cc = scan(read_slicc(sys.argv[1:])) - hh.sort() - cc.sort() - print 'Headers:' - for i in hh: - print ' %s' % i - - print 'Sources:' - for i in cc: - print ' %s' % i diff --git a/src/mem/slicc/parser/parser.yy b/src/mem/slicc/parser/parser.yy deleted file mode 100644 index c8cef3b21..000000000 --- a/src/mem/slicc/parser/parser.yy +++ /dev/null @@ -1,360 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -%{ -#include <string> -#include <stdio.h> -#include <assert.h> -#include "mem/slicc/ast/ASTs.hh" -#include <vector> - -#define YYMAXDEPTH 100000 -#define YYERROR_VERBOSE - -extern char* yytext; - -extern "C" void yyerror(char*); -extern "C" int yylex(); - -%} - -%union { - string* str_ptr; - Vector<string>* string_vector_ptr; - std::vector<string*>* stdstring_vector_ptr; - - // Decls - DeclAST* decl_ptr; - DeclListAST* decl_list_ptr; - Vector<DeclAST*>* decl_vector_ptr; - - // TypeField - TypeFieldAST* type_field_ptr; - Vector<TypeFieldAST*>* type_field_vector_ptr; - - // Type - TypeAST* type_ptr; - Vector<TypeAST*>* type_vector_ptr; - - // Formal Params - FormalParamAST* formal_param_ptr; - Vector<FormalParamAST*>* formal_param_vector_ptr; - - // Statements - StatementAST* statement_ptr; - StatementListAST* statement_list_ptr; - Vector<StatementAST*>* statement_vector_ptr; - - // Pairs - PairAST* pair_ptr; - PairListAST* pair_list_ptr; - - // Expressions - VarExprAST* var_expr_ptr; - ExprAST* expr_ptr; - Vector<ExprAST*>* expr_vector_ptr; -} - -%type <type_ptr> type void type_or_void -%type <type_vector_ptr> types type_list - - // Formal Params -%type <formal_param_ptr> formal_param -%type <formal_param_vector_ptr> formal_params formal_param_list - -%type <str_ptr> ident field -%type <string_vector_ptr> ident_list idents - -%type <statement_ptr> statement if_statement -%type <statement_list_ptr> statement_list -%type <statement_vector_ptr> statements - -%type <decl_ptr> decl -%type <decl_list_ptr> decl_list -%type <decl_vector_ptr> decls - -%type <type_field_vector_ptr> type_members type_enums type_methods -%type <type_field_ptr> type_member type_enum type_method - -%type <var_expr_ptr> var -%type <expr_ptr> expr literal enumeration -%type <expr_vector_ptr> expr_list - -%type <pair_ptr> pair -%type <pair_list_ptr> pair_list pairs - -%token <str_ptr> IDENT STRING NUMBER FLOATNUMBER LIT_BOOL VOID -%token <str_ptr> IMBED IMBED_TYPE -%token CHIP THIS -%token ASSIGN DOUBLE_COLON DOT SEMICOLON COLON -%token GLOBAL_DECL MACHINE_DECL IN_PORT_DECL OUT_PORT_DECL -%token PEEK ENQUEUE COPY_HEAD CHECK_ALLOCATE CHECK_STOP_SLOTS -//%token DEQUEUE REMOVE_EARLY SKIP_EARLY PEEK_EARLY -%token DEBUG_EXPR_TOKEN DEBUG_MSG_TOKEN -%token ACTION_DECL TRANSITION_DECL TYPE_DECL STRUCT_DECL EXTERN_TYPE_DECL ENUM_DECL -%token TYPE_FIELD OTHER IF ELSE RETURN NEW - -%token <str_ptr> EQ NE '<' '>' LE GE NOT AND OR PLUS DASH STAR SLASH RIGHTSHIFT LEFTSHIFT - -%left OR -%left AND -%nonassoc EQ NE -%nonassoc '<' '>' GE LE -%left PLUS DASH -%left STAR SLASH -%nonassoc NOT -%nonassoc DOUBLE_COLON DOT '[' - -%% - -file: decl_list { g_decl_list_ptr = $1; } - -decl_list: decls { $$ = new DeclListAST($1); } - -decls: decl decls { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector<DeclAST*>; } - ; - -decl: MACHINE_DECL '(' ident pair_list ')' ':' formal_param_list '{' decl_list '}' { $$ = new MachineAST($3, $4, $7, $9); } - | ACTION_DECL '(' ident pair_list ')' statement_list { $$ = new ActionDeclAST($3, $4, $6); } - | IN_PORT_DECL '(' ident ',' type ',' var pair_list ')' statement_list { $$ = new InPortDeclAST($3, $5, $7, $8, $10); } - | OUT_PORT_DECL '(' ident ',' type ',' var pair_list ')' SEMICOLON { $$ = new OutPortDeclAST($3, $5, $7, $8); } - | TRANSITION_DECL '(' ident_list ',' ident_list ',' ident pair_list ')' ident_list { $$ = new TransitionDeclAST($3, $5, $7, $8, $10); } - | TRANSITION_DECL '(' ident_list ',' ident_list pair_list ')' ident_list { $$ = new TransitionDeclAST($3, $5, NULL, $6, $8); } - | EXTERN_TYPE_DECL '(' type pair_list ')' SEMICOLON { $4->addPair(new PairAST("external", "yes")); $$ = new TypeDeclAST($3, $4, NULL); } - | EXTERN_TYPE_DECL '(' type pair_list ')' '{' type_methods '}' { $4->addPair(new PairAST("external", "yes")); $$ = new TypeDeclAST($3, $4, $7); } - | GLOBAL_DECL '(' type pair_list ')' '{' type_members '}' { $4->addPair(new PairAST("global", "yes"));$$ = new TypeDeclAST($3, $4, $7); } - | STRUCT_DECL '(' type pair_list ')' '{' type_members '}' { $$ = new TypeDeclAST($3, $4, $7); } - | ENUM_DECL '(' type pair_list ')' '{' type_enums '}' { $4->addPair(new PairAST("enumeration", "yes")); $$ = new EnumDeclAST($3, $4, $7); } - | type ident pair_list SEMICOLON { $$ = new ObjDeclAST($1, $2, $3); } - | type ident '(' formal_param_list ')' pair_list SEMICOLON { $$ = new FuncDeclAST($1, $2, $4, $6, NULL); } // non-void function - | void ident '(' formal_param_list ')' pair_list SEMICOLON { $$ = new FuncDeclAST($1, $2, $4, $6, NULL); } // void function - | type ident '(' formal_param_list ')' pair_list statement_list { $$ = new FuncDeclAST($1, $2, $4, $6, $7); } // non-void function - | void ident '(' formal_param_list ')' pair_list statement_list { $$ = new FuncDeclAST($1, $2, $4, $6, $7); } // void function - ; - -// Type fields - -type_members: type_member type_members { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector<TypeFieldAST*>; } - ; - -type_member: type ident pair_list SEMICOLON { $$ = new TypeFieldMemberAST($1, $2, $3, NULL); } - | type ident ASSIGN expr SEMICOLON { $$ = new TypeFieldMemberAST($1, $2, new PairListAST(), $4); } - ; - -// Methods -type_methods: type_method type_methods { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector<TypeFieldAST*>; } - ; - -type_method: type_or_void ident '(' type_list ')' pair_list SEMICOLON { $$ = new TypeFieldMethodAST($1, $2, $4, $6); } - ; - -// Enum fields -type_enums: type_enum type_enums { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector<TypeFieldAST*>; } - ; - -type_enum: ident pair_list SEMICOLON { $$ = new TypeFieldEnumAST($1, $2); } - ; - -// Type -type_list : types { $$ = $1; } - | { $$ = new Vector<TypeAST*>; } - ; - -types : type ',' types { $3->insertAtTop($1); $$ = $3; } - | type { $$ = new Vector<TypeAST*>; $$->insertAtTop($1); } - ; - -type: ident { $$ = new TypeAST($1); } - ; - -void: VOID { $$ = new TypeAST($1); } - ; - -type_or_void: type { $$ = $1; } - | void { $$ = $1; } - ; - -// Formal Param -formal_param_list : formal_params { $$ = $1; } - | { $$ = new Vector<FormalParamAST*>; } - ; - -formal_params : formal_param ',' formal_params { $3->insertAtTop($1); $$ = $3; } - | formal_param { $$ = new Vector<FormalParamAST*>; $$->insertAtTop($1); } - ; - -formal_param : type ident { $$ = new FormalParamAST($1, $2); } - ; - -// Idents and lists -ident: IDENT { $$ = $1; }; - -ident_list: '{' idents '}' { $$ = $2; } - | ident { $$ = new Vector<string>; $$->insertAtTop(*($1)); delete $1; } - ; - -idents: ident SEMICOLON idents { $3->insertAtTop(*($1)); $$ = $3; delete $1; } - | ident ',' idents { $3->insertAtTop(*($1)); $$ = $3; delete $1; } - | ident idents { $2->insertAtTop(*($1)); $$ = $2; delete $1; } - | { $$ = new Vector<string>; } - ; - -// Pair and pair lists -pair_list: ',' pairs { $$ = $2; } - | { $$ = new PairListAST(); } - -pairs : pair ',' pairs { $3->addPair($1); $$ = $3; } - | pair { $$ = new PairListAST(); $$->addPair($1); } - ; - -pair : ident '=' STRING { $$ = new PairAST($1, $3); } - | ident '=' ident { $$ = new PairAST($1, $3); } - | STRING { $$ = new PairAST(new string("short"), $1); } - ; - -// Below are the rules for action descriptions - -statement_list: '{' statements '}' { $$ = new StatementListAST($2); } - ; - -statements: statement statements { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector<StatementAST*>; } - ; - -expr_list: expr ',' expr_list { $3->insertAtTop($1); $$ = $3; } - | expr { $$ = new Vector<ExprAST*>; $$->insertAtTop($1); } - | { $$ = new Vector<ExprAST*>; } - ; - -statement: expr SEMICOLON { $$ = new ExprStatementAST($1); } - | expr ASSIGN expr SEMICOLON { $$ = new AssignStatementAST($1, $3); } - | ENQUEUE '(' var ',' type pair_list ')' statement_list { $$ = new EnqueueStatementAST($3, $5, $6, $8); } - | PEEK '(' var ',' type ')' statement_list { $$ = new PeekStatementAST($3, $5, $7, "peek"); } -// | PEEK_EARLY '(' var ',' type ')' statement_list { $$ = new PeekStatementAST($3, $5, $7, "peekEarly"); } - | COPY_HEAD '(' var ',' var pair_list ')' SEMICOLON { $$ = new CopyHeadStatementAST($3, $5, $6); } - | CHECK_ALLOCATE '(' var ')' SEMICOLON { $$ = new CheckAllocateStatementAST($3); } - | CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMICOLON { $$ = new CheckStopSlotsStatementAST($3, $5, $7); } - | if_statement { $$ = $1; } - | RETURN expr SEMICOLON { $$ = new ReturnStatementAST($2); } - ; - -if_statement: IF '(' expr ')' statement_list ELSE statement_list { $$ = new IfStatementAST($3, $5, $7); } - | IF '(' expr ')' statement_list { $$ = new IfStatementAST($3, $5, NULL); } - | IF '(' expr ')' statement_list ELSE if_statement { $$ = new IfStatementAST($3, $5, new StatementListAST($7)); } - ; - -expr: var { $$ = $1; } - | literal { $$ = $1; } - | enumeration { $$ = $1; } - | ident '(' expr_list ')' { $$ = new FuncCallExprAST($1, $3); } - | NEW type { $$ = new NewExprAST($2); } - -// globally access a local chip component and call a method - | THIS DOT var '[' expr ']' DOT var DOT ident '(' expr_list ')' { $$ = new ChipComponentAccessAST($3, $5, $8, $10, $12 ); } -// globally access a local chip component and access a data member - | THIS DOT var '[' expr ']' DOT var DOT field { $$ = new ChipComponentAccessAST($3, $5, $8, $10 ); } -// globally access a specified chip component and call a method - | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' expr_list ')' { $$ = new ChipComponentAccessAST($3, $6, $8, $11, $13, $15 ); } -// globally access a specified chip component and access a data member - | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field { $$ = new ChipComponentAccessAST($3, $6, $8, $11, $13 ); } - - - | expr DOT field { $$ = new MemberExprAST($1, $3); } - | expr DOT ident '(' expr_list ')' { $$ = new MethodCallExprAST($1, $3, $5); } - | type DOUBLE_COLON ident '(' expr_list ')' { $$ = new MethodCallExprAST($1, $3, $5); } - | expr '[' expr_list ']' { $$ = new MethodCallExprAST($1, new string("lookup"), $3); } - | expr STAR expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr SLASH expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr PLUS expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr DASH expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr '<' expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr '>' expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr LE expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr GE expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr EQ expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr NE expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr AND expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr OR expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr RIGHTSHIFT expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr LEFTSHIFT expr { $$ = new InfixOperatorExprAST($1, $2, $3); } -// | NOT expr { $$ = NULL; } // FIXME - unary not -// | DASH expr %prec NOT { $$ = NULL; } // FIXME - unary minus - | '(' expr ')' { $$ = $2; } - ; - -literal: STRING { $$ = new LiteralExprAST($1, "string"); } - | NUMBER { $$ = new LiteralExprAST($1, "int"); } - | FLOATNUMBER { $$ = new LiteralExprAST($1, "int"); } - | LIT_BOOL { $$ = new LiteralExprAST($1, "bool"); } - ; - -enumeration: ident ':' ident { $$ = new EnumExprAST(new TypeAST($1), $3); } - ; - -var: ident { $$ = new VarExprAST($1); } - ; - -field: ident { $$ = $1; } - ; - -%% - -extern FILE *yyin; - -DeclListAST* parse(string filename) -{ - FILE *file; - file = fopen(filename.c_str(), "r"); - if (!file) { - cerr << "Error: Could not open file: " << filename << endl; - exit(1); - } - g_line_number = 1; - g_file_name() = filename; - yyin = file; - g_decl_list_ptr = NULL; - yyparse(); - return g_decl_list_ptr; -} - -extern "C" void yyerror(char* s) -{ - fprintf(stderr, "%s:%d: %s at %s\n", g_file_name().c_str(), g_line_number, s, yytext); - exit(1); -} - diff --git a/src/mem/slicc/slicc_global.hh b/src/mem/slicc/slicc_global.hh deleted file mode 100644 index 40a00c9d2..000000000 --- a/src/mem/slicc/slicc_global.hh +++ /dev/null @@ -1,125 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SLICC_GLOBAL_H -#define SLICC_GLOBAL_H - -#include <cassert> - -#include "mem/gems_common/std-includes.hh" -#include "mem/gems_common/Map.hh" - -typedef unsigned char uint8; -typedef unsigned int uint32; -typedef unsigned long long uint64; - -typedef signed char int8; -typedef int int32; -typedef long long int64; - -typedef long long integer_t; -typedef unsigned long long uinteger_t; - -const bool ASSERT_FLAG = true; - -// when CHECK_RESOURCE_DEADLOCK is enabled, slicc will generate additional code -// that works in conjuction with the resources rank value specified in the protocol -// to detect invalid resource stalls as soon as they occur. -const bool CHECK_INVALID_RESOURCE_STALLS = false; - -#undef assert -#define assert(EXPR) ASSERT(EXPR) - -#define ASSERT(EXPR)\ -{\ - if (ASSERT_FLAG) {\ - if (!(EXPR)) {\ - cerr << "failed assertion '"\ - << #EXPR << "' at fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << endl;\ - if(isatty(STDERR_FILENO)) {\ - cerr << "At this point you might want to attach a debug to ";\ - cerr << "the running and get to the" << endl;\ - cerr << "crash site; otherwise press enter to continue" << endl;\ - cerr << "PID: " << getpid();\ - cerr << endl << flush; \ - char c; \ - cin.get(c); \ - }\ - abort();\ - }\ - }\ -} - -class State; -class Event; -class Symbol; -class Var; - -namespace __gnu_cxx { - template <> struct hash<State*> - { - size_t operator()(State* s) const { return (size_t) s; } - }; - template <> struct hash<Event*> - { - size_t operator()(Event* s) const { return (size_t) s; } - }; - template <> struct hash<Symbol*> - { - size_t operator()(Symbol* s) const { return (size_t) s; } - }; - template <> struct hash<Var*> - { - size_t operator()(Var* s) const { return (size_t) s; } - }; -} // namespace __gnu_cxx - -namespace std { - template <> struct equal_to<Event*> - { - bool operator()(Event* s1, Event* s2) const { return s1 == s2; } - }; - template <> struct equal_to<State*> - { - bool operator()(State* s1, State* s2) const { return s1 == s2; } - }; - template <> struct equal_to<Symbol*> - { - bool operator()(Symbol* s1, Symbol* s2) const { return s1 == s2; } - }; - template <> struct equal_to<Var*> - { - bool operator()(Var* s1, Var* s2) const { return s1 == s2; } - }; -} // namespace std - -#endif //SLICC_GLOBAL_H diff --git a/src/mem/slicc/symbols/Action.hh b/src/mem/slicc/symbols/Action.hh deleted file mode 100644 index dbb0c836a..000000000 --- a/src/mem/slicc/symbols/Action.hh +++ /dev/null @@ -1,52 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -#ifndef ACTION_H -#define ACTION_H - -#include "mem/slicc/symbols/Symbol.hh" - -class Action : public Symbol { -public: - Action(string id, - const Map<Var*, string>& resources, - const Location& location, - const Map<string, string>& pairs) : Symbol(id, location, pairs) { m_resources = resources; } - const Map<Var*, string>& getResources() const { return m_resources; } - void print(ostream& out) const { out << "[Action: " << getIdent() << "]"; } - -private: - Map<Var*, string> m_resources; -}; - -#endif //ACTION_H diff --git a/src/mem/slicc/symbols/Action.py b/src/mem/slicc/symbols/Action.py new file mode 100644 index 000000000..880fab15a --- /dev/null +++ b/src/mem/slicc/symbols/Action.py @@ -0,0 +1,38 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class Action(Symbol): + def __init__(self, table, ident, resources, location, pairs): + super(Action, self).__init__(table, ident, location, pairs) + self.resources = resources + + def __repr__(self): + return "[Action: %s]" % self.ident + +__all__ = [ "Action" ] diff --git a/src/mem/slicc/symbols/Event.hh b/src/mem/slicc/symbols/Event.hh deleted file mode 100644 index 40cefc982..000000000 --- a/src/mem/slicc/symbols/Event.hh +++ /dev/null @@ -1,45 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -#ifndef EVENT_H -#define EVENT_H - -#include "mem/slicc/symbols/Symbol.hh" - -class Event : public Symbol { -public: - Event(string id, const Location& location, const Map<string, string>& pairs) : Symbol(id, location, pairs) {} - void print(ostream& out) const { out << "[Event: " << getIdent() << "]"; } -}; - -#endif //EVENT_H diff --git a/src/mem/slicc/symbols/Event.py b/src/mem/slicc/symbols/Event.py new file mode 100644 index 000000000..9ff4d8ba7 --- /dev/null +++ b/src/mem/slicc/symbols/Event.py @@ -0,0 +1,34 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class Event(Symbol): + def __repr__(self): + return "[Event: %s]" % self.ident + +__all__ = [ "Event" ] diff --git a/src/mem/slicc/symbols/Func.cc b/src/mem/slicc/symbols/Func.cc deleted file mode 100644 index d29138b38..000000000 --- a/src/mem/slicc/symbols/Func.cc +++ /dev/null @@ -1,143 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Func.cc - * - * Description: See Func.hh - * - * $Id$ - * - */ - -#include "mem/slicc/symbols/Func.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -Func::Func(string id, const Location& location, - Type* type_ptr, const Vector<Type*>& param_type_vec, - const Vector<string>& param_string_vec, string body, - const Map<string, string>& pairs, StateMachine* machine_ptr) - : Symbol(id, location, pairs) -{ - m_type_ptr = type_ptr; - m_param_type_vec = param_type_vec; - m_param_string_vec = param_string_vec; - m_body = body; - m_isInternalMachineFunc = false; - - if (machine_ptr == NULL) { - m_c_ident = id; - } else if (existPair("external") || existPair("primitive")) { - m_c_ident = id; - } else { - m_machineStr = machine_ptr->toString(); - m_c_ident = m_machineStr + "_" + id; // Append with machine name - m_isInternalMachineFunc = true; - } -} - -void Func::funcPrototype(string& code) const -{ - if (isExternal()) { - // Do nothing - } else { - string return_type = m_type_ptr->cIdent(); - Type* void_type_ptr = g_sym_table.getType("void"); - if (existPair("return_by_ref") && (m_type_ptr != void_type_ptr)) { - return_type += "&"; - } - code += return_type + " " + cIdent() + "("; - int size = m_param_string_vec.size(); - for(int i=0; i<size; i++) { - // Generate code - if (i != 0) { - code += ", "; - } - code += m_param_string_vec[i]; - } - code += ");\n"; - } -} - -// This write a function of object Chip -void Func::writeCFiles(string path) -{ - if (isExternal()) { - // Do nothing - } else { - ostringstream out; - - // Header - out << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl; - out << endl; - out << "#include \"mem/protocol/Types.hh\"" << endl; - if (m_isInternalMachineFunc) { - out << "#include \"mem/protocol/" << m_machineStr << "_Controller.hh\"" << endl; - } - out << endl; - - // Generate function header - string code; - Type* void_type_ptr = g_sym_table.getType("void"); - string return_type = m_type_ptr->cIdent(); - code += return_type; - if (existPair("return_by_ref") && m_type_ptr != void_type_ptr) { - code += "&"; - } - if (!m_isInternalMachineFunc) { - code += " Chip::" + cIdent() + "("; - } else { - code += " " + m_machineStr + "_Controller::" + cIdent() + "("; - } - int size = m_param_type_vec.size(); - for(int i=0; i<size; i++) { - // Generate code - if (i != 0) { - code += ", "; - } - code += m_param_string_vec[i]; - } - code += ")"; - - // Function body - code += "\n{\n"; - code += m_body; - code += "}\n"; - out << code << endl; - - // Write it out - conditionally_write_file(path + cIdent() + ".cc", out); - } -} - -void Func::print(ostream& out) const -{ -} diff --git a/src/mem/slicc/symbols/Func.hh b/src/mem/slicc/symbols/Func.hh deleted file mode 100644 index 8f8548bb0..000000000 --- a/src/mem/slicc/symbols/Func.hh +++ /dev/null @@ -1,96 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Func.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef FUNC_H -#define FUNC_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/symbols/Type.hh" -class StateMachine; - -class Func : public Symbol { -public: - // Constructors - Func(string id, const Location& location, - Type* type_ptr, const Vector<Type*>& param_type_vec, const Vector<string>& param_string_vec, - string body, const Map<string, string>& pairs, StateMachine* machine_ptr); - - // Destructor - ~Func() {} - - // Public Methods - string cIdent() const { return m_c_ident; } - const Vector<Type*>& getParamTypes() const { return m_param_type_vec; } - Type* getReturnType() const { return m_type_ptr; } - void writeCFiles(string path) ; - void funcPrototype(string& code) const; - bool isExternal() const { return existPair("external"); } - bool isInternalMachineFunc() const { return m_isInternalMachineFunc; } - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - Func(const Func& obj); - Func& operator=(const Func& obj); - - // Data Members (m_ prefix) - Type* m_type_ptr; - Vector<Type*> m_param_type_vec; - Vector<string> m_param_string_vec; - string m_body; - string m_c_ident; - string m_machineStr; - bool m_isInternalMachineFunc; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Func& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Func& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //FUNC_H diff --git a/src/mem/slicc/symbols/Func.py b/src/mem/slicc/symbols/Func.py new file mode 100644 index 000000000..5c812a96f --- /dev/null +++ b/src/mem/slicc/symbols/Func.py @@ -0,0 +1,107 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.symbols.Symbol import Symbol +from slicc.symbols.Type import Type + +class Func(Symbol): + def __init__(self, table, ident, location, return_type, param_types, + param_strings, body, pairs, machine): + super(Func, self).__init__(table, ident, location, pairs) + self.return_type = return_type + self.param_types = param_types + self.param_strings = param_strings + self.body = body + self.isInternalMachineFunc = False + + if machine is None: + self.c_ident = ident + elif "external" in self or "primitive" in self: + self.c_ident = ident + else: + self.machineStr = str(machine) + # Append with machine name + self.c_ident = "%s_%s" % (self.machineStr, ident) + self.isInternalMachineFunc = True + + def __repr__(self): + return "" + + @property + def prototype(self): + if "external" in self: + return "" + + return_type = self.return_type.c_ident + void_type = self.symtab.find("void", Type) + if "return_by_ref" in self and self.return_type != void_type: + return_type += "&" + + return "%s %s(%s);" % (return_type, self.c_ident, + ", ".join(self.param_strings)) + + def writeCodeFiles(self, path): + '''This write a function of object Chip''' + if "external" in self: + return + + code = code_formatter() + + # Header + code(''' +/** Auto generated C++ code started by $__file__:$__line__ */ + +#include "mem/protocol/Types.hh" +''') + + if self.isInternalMachineFunc: + code('#include "mem/protocol/${{self.machineStr}}_Controller.hh"') + + # Generate function header + void_type = self.symtab.find("void", Type) + return_type = self.return_type.c_ident + if "return_by_ref" in self and self.return_type != void_type: + return_type += "&" + + if self.isInternalMachineFunc: + klass = "%s_Controller" % self.machineStr + else: + klass = "Chip" + + params = ', '.join(self.param_strings) + + code(''' +$return_type ${klass}::${{self.c_ident}}($params) +{ +${{self.body}} +} +''') + code.write(path, "%s.cc" % self.c_ident) + +__all__ = [ "Func" ] diff --git a/src/mem/slicc/symbols/State.hh b/src/mem/slicc/symbols/State.hh deleted file mode 100644 index 39900d506..000000000 --- a/src/mem/slicc/symbols/State.hh +++ /dev/null @@ -1,45 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -#ifndef STATE_H -#define STATE_H - -#include "mem/slicc/symbols/Symbol.hh" - -class State : public Symbol { -public: - State(string id, const Location& location, const Map<string, string>& pairs) : Symbol(id, location, pairs) {} - void print(ostream& out) const { out << "[State: " << getIdent() << "]"; } -}; - -#endif //STATE_H diff --git a/src/mem/slicc/symbols/State.py b/src/mem/slicc/symbols/State.py new file mode 100644 index 000000000..123693256 --- /dev/null +++ b/src/mem/slicc/symbols/State.py @@ -0,0 +1,34 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class State(Symbol): + def __repr__(self): + return "[State: %s]" % self.ident + +__all__ = [ "State" ] diff --git a/src/mem/slicc/symbols/StateMachine.cc b/src/mem/slicc/symbols/StateMachine.cc deleted file mode 100644 index 0edfedc43..000000000 --- a/src/mem/slicc/symbols/StateMachine.cc +++ /dev/null @@ -1,1481 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/generator/html_gen.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/slicc/symbols/Event.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Transition.hh" -#include "mem/slicc/symbols/Var.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/gems_common/util.hh" -#include "mem/gems_common/Vector.hh" -#include "mem/slicc/ast/FormalParamAST.hh" - -#include <set> - -StateMachine::StateMachine(string ident, const Location& location, const Map<string, string>& pairs, Vector<FormalParamAST*>* config_parameters) - : Symbol(ident, location, pairs) -{ - m_table_built = false; - m_config_parameters = config_parameters; - - for (int i=0; i< m_config_parameters->size(); i++) { - Var* var = new Var(m_config_parameters->ref(i)->getName(), - location, - m_config_parameters->ref(i)->getType(), - "m_"+m_config_parameters->ref(i)->getName(), - Map<string, string>(), - this); - g_sym_table.registerSym(m_config_parameters->ref(i)->getName(), var); - } -} - -StateMachine::~StateMachine() -{ - // FIXME - // assert(0); -} - -void StateMachine::addState(State* state_ptr) -{ - assert(m_table_built == false); - m_state_map.add(state_ptr, m_states.size()); - m_states.insertAtBottom(state_ptr); -} - -void StateMachine::addEvent(Event* event_ptr) -{ - assert(m_table_built == false); - m_event_map.add(event_ptr, m_events.size()); - m_events.insertAtBottom(event_ptr); -} - -void StateMachine::addAction(Action* action_ptr) -{ - assert(m_table_built == false); - - // Check for duplicate action - int size = m_actions.size(); - for(int i=0; i<size; i++) { - if (m_actions[i]->getIdent() == action_ptr->getIdent()) { - m_actions[i]->warning("Duplicate action definition: " + m_actions[i]->getIdent()); - action_ptr->error("Duplicate action definition: " + action_ptr->getIdent()); - } - if (m_actions[i]->getShorthand() == action_ptr->getShorthand()) { - m_actions[i]->warning("Duplicate action shorthand: " + m_actions[i]->getIdent()); - m_actions[i]->warning(" shorthand = " + m_actions[i]->getShorthand()); - action_ptr->warning("Duplicate action shorthand: " + action_ptr->getIdent()); - action_ptr->error(" shorthand = " + action_ptr->getShorthand()); - } - } - - m_actions.insertAtBottom(action_ptr); -} - -void StateMachine::addTransition(Transition* trans_ptr) -{ - assert(m_table_built == false); - trans_ptr->checkIdents(m_states, m_events, m_actions); - m_transitions.insertAtBottom(trans_ptr); -} - -void StateMachine::addFunc(Func* func_ptr) -{ - // register func in the symbol table - g_sym_table.registerSym(func_ptr->toString(), func_ptr); - m_internal_func_vec.insertAtBottom(func_ptr); -} - -void StateMachine::buildTable() -{ - assert(m_table_built == false); - int numStates = m_states.size(); - int numEvents = m_events.size(); - int numTransitions = m_transitions.size(); - int stateIndex, eventIndex; - - for(stateIndex=0; stateIndex < numStates; stateIndex++) { - m_table.insertAtBottom(Vector<Transition*>()); - for(eventIndex=0; eventIndex < numEvents; eventIndex++) { - m_table[stateIndex].insertAtBottom(NULL); - } - } - - for(int i=0; i<numTransitions; i++) { - Transition* trans_ptr = m_transitions[i]; - - // Track which actions we touch so we know if we use them all -- - // really this should be done for all symbols as part of the - // symbol table, then only trigger it for Actions, States, Events, - // etc. - - Vector<Action*> actions = trans_ptr->getActions(); - for(int actionIndex=0; actionIndex < actions.size(); actionIndex++) { - actions[actionIndex]->markUsed(); - } - - stateIndex = getStateIndex(trans_ptr->getStatePtr()); - eventIndex = getEventIndex(trans_ptr->getEventPtr()); - if (m_table[stateIndex][eventIndex] != NULL) { - m_table[stateIndex][eventIndex]->warning("Duplicate transition: " + m_table[stateIndex][eventIndex]->toString()); - trans_ptr->error("Duplicate transition: " + trans_ptr->toString()); - } - m_table[stateIndex][eventIndex] = trans_ptr; - } - - // Look at all actions to make sure we used them all - for(int actionIndex=0; actionIndex < m_actions.size(); actionIndex++) { - Action* action_ptr = m_actions[actionIndex]; - if (!action_ptr->wasUsed()) { - string error_msg = "Unused action: " + action_ptr->getIdent(); - if (action_ptr->existPair("desc")) { - error_msg += ", " + action_ptr->getDescription(); - } - action_ptr->warning(error_msg); - } - } - - m_table_built = true; -} - -const Transition* StateMachine::getTransPtr(int stateIndex, int eventIndex) const -{ - return m_table[stateIndex][eventIndex]; -} - -// *********************** // -// ******* C Files ******* // -// *********************** // - -void StateMachine::writeCFiles(string path) -{ - string comp = getIdent(); - string filename; - - // Output the method declarations for the class declaration - { - ostringstream sstr; - printControllerH(sstr, comp); - conditionally_write_file(path + comp + "_Controller.hh", sstr); - } - - // Output switch statement for transition table - { - ostringstream sstr; - printCSwitch(sstr, comp); - conditionally_write_file(path + comp + "_Transitions.cc", sstr); - } - - // Output the actions for performing the actions - { - ostringstream sstr; - printControllerC(sstr, comp); - conditionally_write_file(path + comp + "_Controller.cc", sstr); - } - - // Output the wakeup loop for the events - { - ostringstream sstr; - printCWakeup(sstr, comp); - conditionally_write_file(path + comp + "_Wakeup.cc", sstr); - } - - // Profiling - { - ostringstream sstr; - printProfilerC(sstr, comp); - conditionally_write_file(path + comp + "_Profiler.cc", sstr); - } - { - ostringstream sstr; - printProfilerH(sstr, comp); - conditionally_write_file(path + comp + "_Profiler.hh", sstr); - } - - // Write internal func files - for(int i=0; i<m_internal_func_vec.size(); i++) { - m_internal_func_vec[i]->writeCFiles(path); - } - -} - -void StateMachine::printControllerH(ostream& out, string component) -{ - - m_message_buffer_names.clear(); - - out << "/** \\file " << getIdent() << ".hh" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " * Created by slicc definition of Module \"" << getShorthand() << "\"" << endl; - out << " */" << endl; - out << endl; - out << "#ifndef " << component << "_CONTROLLER_H" << endl; - out << "#define " << component << "_CONTROLLER_H" << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/ruby/common/Consumer.hh\"" << endl; - out << "#include \"mem/ruby/slicc_interface/AbstractController.hh\"" << endl; - out << "#include \"mem/protocol/TransitionResult.hh\"" << endl; - out << "#include \"mem/protocol/Types.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Profiler.hh\"" << endl; - - // include object classes - std::set<string> seen_types; - for(int i=0; i<numObjects(); i++) { - Var* var = m_objs[i]; - if (seen_types.count(var->getType()->cIdent()) == 0) { - out << "#include \"mem/protocol/" << var->getType()->cIdent() << ".hh\"" << endl; - // out << "class " << var->getType()->cIdent() << ";" << endl; - seen_types.insert(var->getType()->cIdent()); - } - } - - out << endl; - - // for adding information to the protocol debug trace - out << "extern stringstream " << component << "_" << "transitionComment;" << endl; - - out << "class " << component << "_Controller : public AbstractController {" << endl; - - /* the coherence checker needs to call isBlockExclusive() and isBlockShared() - making the Chip a friend class is an easy way to do this for now */ - out << "#ifdef CHECK_COHERENCE" << endl; - out << "#endif /* CHECK_COHERENCE */" << endl; - - out << "public:" << endl; - // out << " " << component << "_Controller(int version, Network* net_ptr);" << endl; - out << " " << component << "_Controller(const string & name);" << endl; - out << " static int getNumControllers();" << endl; - out << " void init(Network* net_ptr, const vector<string> & argv);" << endl; - out << " MessageBuffer* getMandatoryQueue() const;" << endl; - out << " const int & getVersion() const;" << endl; - out << " const string toString() const;" << endl; - out << " const string getName() const;" << endl; - out << " const MachineType getMachineType() const;" << endl; - out << " void print(ostream& out) const;" << endl; - out << " void printConfig(ostream& out) const;" << endl; - out << " void wakeup();" << endl; - out << " void set_atomic(Address addr);" << endl; - out << " void clear_atomic(Address addr);" << endl; - out << " void reset_atomics();" << endl; - out << " void printStats(ostream& out) const { s_profiler.dumpStats(out); }" << endl; - out << " void clearStats() { s_profiler.clearStats(); }" << endl; - out << "private:" << endl; -//added by SS -// found_to_mem = 0; - for(int i=0;i<m_config_parameters->size();i++){ - out << " int m_" << m_config_parameters->ref(i)->getName() << ";" << endl; - } - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - out << " int servicing_atomic;" << endl; - out << " bool started_receiving_writes;" << endl; - out << " Address locked_read_request1;" << endl; - out << " Address locked_read_request2;" << endl; - out << " Address locked_read_request3;" << endl; - out << " Address locked_read_request4;" << endl; - out << " int read_counter;" << endl; - } - out << " int m_number_of_TBEs;" << endl; - - out << " TransitionResult doTransition(" << component << "_Event event, " << component - << "_State state, const Address& addr"; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", int priority"; - } - out << "); // in " << component << "_Transitions.cc" << endl; - out << " TransitionResult doTransitionWorker(" << component << "_Event event, " << component - << "_State state, " << component << "_State& next_state, const Address& addr"; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", int priority"; - } - out << "); // in " << component << "_Transitions.cc" << endl; - out << " string m_name;" << endl; - out << " int m_transitions_per_cycle;" << endl; - out << " int m_buffer_size;" << endl; - out << " int m_recycle_latency;" << endl; - out << " map< string, string > m_cfg;" << endl; - out << " NodeID m_version;" << endl; - out << " Network* m_net_ptr;" << endl; - out << " MachineID m_machineID;" << endl; - out << " " << component << "_Profiler s_profiler;" << endl; - out << " static int m_num_controllers;" << endl; - - // internal function protypes - out << " // Internal functions" << endl; - for(int i=0; i<m_internal_func_vec.size(); i++) { - Func* func = m_internal_func_vec[i]; - string proto; - func->funcPrototype(proto); - if (proto != "") { - out << " " << proto; - } - } - - out << " // Actions" << endl; - for(int i=0; i < numActions(); i++) { - const Action& action = getAction(i); - out << "/** \\brief " << action.getDescription() << "*/" << endl; - out << " void " << action.getIdent() << "(const Address& addr);" << endl; - } - - // the controller internal variables - out << " // Object" << endl; - for(int i=0; i < numObjects(); i++) { - const Var* var = m_objs[i]; - string template_hack = ""; - if (var->existPair("template_hack")) { - template_hack = var->lookupPair("template_hack"); - } - out << " " << var->getType()->cIdent() << template_hack << "* m_" - << var->cIdent() << "_ptr;" << endl; - - string str = "m_"+ var->cIdent() + "_ptr"; - if (var->getType()->cIdent() == "MessageBuffer") - m_message_buffer_names.push_back(str); - - } - - - out << "};" << endl; - out << "#endif // " << component << "_CONTROLLER_H" << endl; -} - -void StateMachine::printControllerC(ostream& out, string component) -{ - out << "/** \\file " << getIdent() << ".cc" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " * Created by slicc definition of Module \"" << getShorthand() << "\"" << endl; - out << " */" << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; - out << "#include \"mem/protocol/Types.hh\"" << endl; - out << "#include \"mem/ruby/system/System.hh\"" << endl; - - // include object classes - std::set<string> seen_types; - for(int i=0; i<numObjects(); i++) { - Var* var = m_objs[i]; - if (seen_types.count(var->getType()->cIdent()) == 0) { - out << "#include \"mem/protocol/" << var->getType()->cIdent() << ".hh\"" << endl; - seen_types.insert(var->getType()->cIdent()); - } - - } - - out << endl; - - out << "int " << component << "_Controller::m_num_controllers = 0;" << endl; - - // for adding information to the protocol debug trace - out << "stringstream " << component << "_" << "transitionComment;" << endl; - out << "#define APPEND_TRANSITION_COMMENT(str) (" << component << "_" << "transitionComment << str)" << endl; - - out << "/** \\brief constructor */" << endl; - out << component << "_Controller::" << component - // << "_Controller(int version, Network* net_ptr)" << endl; - << "_Controller(const string & name)" << endl; - out << " : m_name(name)" << endl; - out << "{ " << endl; - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - out << " servicing_atomic = 0;" << endl; - out << " started_receiving_writes = false;" << endl; - out << " locked_read_request1 = Address(-1);" << endl; - out << " locked_read_request2 = Address(-1);" << endl; - out << " locked_read_request3 = Address(-1);" << endl; - out << " locked_read_request4 = Address(-1);" << endl; - out << " read_counter = 0;" << endl; - } - out << " m_num_controllers++; " << endl; - for(int i=0; i < numObjects(); i++) { - const Var* var = m_objs[i]; - if ( var->cIdent().find("mandatoryQueue") != string::npos) - out << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << "();" << endl; - } - out << "}" << endl << endl; - - out << "void " << component << "_Controller::init(Network * net_ptr, const vector<string> & argv)" << endl; - out << "{" << endl; - out << " for (size_t i=0; i < argv.size(); i+=2) {" << endl; -// out << " printf (\"ARG: %s = %s \\n \", argv[i].c_str(), argv[i+1].c_str());"<< endl; - - out << " if (argv[i] == \"version\") " << endl; - out << " m_version = atoi(argv[i+1].c_str());" << endl; - out << " else if (argv[i] == \"transitions_per_cycle\") " << endl; - out << " m_transitions_per_cycle = atoi(argv[i+1].c_str());" << endl; - out << " else if (argv[i] == \"buffer_size\") " << endl; - out << " m_buffer_size = atoi(argv[i+1].c_str());" << endl; -//added by SS - out << " else if (argv[i] == \"recycle_latency\") " << endl; - out << " m_recycle_latency = atoi(argv[i+1].c_str());" << endl; -//added by SS --> for latency -//for loop on latency_vector to check with argv[i] and assign the value to the related m_latency ... - out << " else if (argv[i] == \"number_of_TBEs\") " << endl; - out << " m_number_of_TBEs = atoi(argv[i+1].c_str());" << endl; - - if (m_config_parameters->size()) { - for(int i= 0 ; i < m_config_parameters->size(); i++) { - out << " else if (argv[i] == \"" << m_config_parameters->ref(i)->getName() << "\")" << endl; - if (m_config_parameters->ref(i)->getTypeName() == "int") - out << " m_" << m_config_parameters->ref(i)->getName() << "=" << "atoi(argv[i+1].c_str());" << endl; - else - assert(0); // only int parameters are supported right now - // if (str == "to_mem_ctrl_latency") - // out << " m_" << (*it)->c_str() << "=" << "atoi(argv[i+1].c_str())+(random() % 5);" << endl; - } - } - out << " }" << endl; - out << " m_net_ptr = net_ptr;" << endl; - out << " m_machineID.type = MachineType_" << component << ";" << endl; - out << " m_machineID.num = m_version;" << endl; - - // make configuration array - out << " for (size_t i=0; i < argv.size(); i+=2) {" << endl; - out << " if (argv[i] != \"version\") " << endl; - out << " m_cfg[argv[i]] = argv[i+1];" << endl; - out << " }" << endl; - - out << endl; - - // initialize objects - out << " // Objects" << endl; - out << " s_profiler.setVersion(m_version);" << endl; - for(int i=0; i < numObjects(); i++) { - const Var* var = m_objs[i]; - if (!var->existPair("network")) { - // Not a network port object - if (var->getType()->existPair("primitive")) { - out << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << ";\n"; - if (var->existPair("default")) { - out << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default") << ";\n"; - } - out << " }\n"; - - } else { - // Normal Object - string template_hack = ""; - if (var->existPair("template_hack")) { - template_hack = var->lookupPair("template_hack"); - } -//added by SS - string str = ""; - int found = 0; - if (var->existPair("factory")) { - out << " m_" << var->cIdent() << "_ptr = " << var->lookupPair("factory"); - } else { - if ( var->cIdent().find("mandatoryQueue") == string::npos) { - - str = " m_" + var->cIdent() + "_ptr = new " + var->getType()->cIdent() + template_hack; - out << str; - if (str.find("TBETable")!=string::npos){ - found = 1; - } - - if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) { - str = ""; - if (var->existPair("constructor_hack")) { - string constructor_hack = var->lookupPair("constructor_hack"); - str = "(" + constructor_hack + ")"; - } else { - str = "()"; - } - if (found) - str = "(m_number_of_TBEs)"; - out << str; - } - } - } - - out << ";\n"; - out << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl; - - if (var->existPair("default")) { - out << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default") - << "; // Object default" << endl; - } else if (var->getType()->hasDefault()) { - out << " (*m_" << var->cIdent() << "_ptr) = " << var->getType()->getDefault() - << "; // Type " << var->getType()->getIdent() << " default" << endl; - } - - // Set ordering - if (var->existPair("ordered") && !var->existPair("trigger_queue")) { - // A buffer - string ordered = var->lookupPair("ordered"); - out << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n"; - } - - // Set randomization - if (var->existPair("random")) { - // A buffer - string value = var->lookupPair("random"); - out << " m_" << var->cIdent() << "_ptr->setRandomization(" << value << ");\n"; - } - - // Set Priority - if (var->getType()->isBuffer() && var->existPair("rank") && !var->existPair("trigger_queue")) { - string rank = var->lookupPair("rank"); - out << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n"; - } - } - } else { - // Network port object - string network = var->lookupPair("network"); - string ordered = var->lookupPair("ordered"); - string vnet = var->lookupPair("virtual_network"); - - assert (var->getMachine() != NULL); - out << " m_" << var->cIdent() << "_ptr = m_net_ptr->get" - << network << "NetQueue(m_version+MachineType_base_number(string_to_MachineType(\"" - << var->getMachine()->getIdent() << "\")), " - << ordered << ", " << vnet << ");\n"; - out << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl; - - // Set ordering - if (var->existPair("ordered")) { - // A buffer - string ordered = var->lookupPair("ordered"); - out << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n"; - } - - // Set randomization - if (var->existPair("random")) { - // A buffer - string value = var->lookupPair("random"); - out << " m_" << var->cIdent() << "_ptr->setRandomization(" << value << ");\n"; - } - - // Set Priority - if (var->existPair("rank")) { - string rank = var->lookupPair("rank"); - out << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n"; - } - - // Set buffer size - if (var->getType()->isBuffer()) { - out << " if (m_buffer_size > 0) {\n"; - out << " m_" << var->cIdent() << "_ptr->setSize(m_buffer_size);\n"; - out << " }\n"; - } - - // set description (may be overriden later by port def) - out << " m_" << var->cIdent() - << "_ptr->setDescription(\"[Version \" + int_to_string(m_version) + \", " - << component << ", name=" << var->cIdent() << "]\");" << endl; - out << endl; - } - } - - // Set the queue consumers - out << endl; - for(int i=0; i < m_in_ports.size(); i++) { - const Var* port = m_in_ports[i]; - out << " " << port->getCode() << ".setConsumer(this);" << endl; - } - - // Set the queue descriptions - out << endl; - for(int i=0; i < m_in_ports.size(); i++) { - const Var* port = m_in_ports[i]; - out << " " << port->getCode() - << ".setDescription(\"[Version \" + int_to_string(m_version) + \", " - << component << ", " << port->toString() << "]\");" << endl; - } - - // Initialize the transition profiling - out << endl; - for(int i=0; i<numTransitions(); i++) { - const Transition& t = getTransition(i); - const Vector<Action*>& action_vec = t.getActions(); - int numActions = action_vec.size(); - - // Figure out if we stall - bool stall = false; - for (int i=0; i<numActions; i++) { - if(action_vec[i]->getIdent() == "z_stall") { - stall = true; - } - } - - // Only possible if it is not a 'z' case - if (!stall) { - out << " s_profiler.possibleTransition(" << component << "_State_" - << t.getStatePtr()->getIdent() << ", " << component << "_Event_" - << t.getEventPtr()->getIdent() << ");" << endl; - } - } - - //added by SS to initialize recycle_latency of message buffers - std::vector<std::string>::const_iterator it; - for ( it=m_message_buffer_names.begin() ; it != m_message_buffer_names.end(); it++ ){ - out << " "<< (*it).c_str() << "->setRecycleLatency(m_recycle_latency);" << endl; - } - - - out << "}" << endl; - - out << endl; - - bool has_mandatory_q = false; - for(int i=0; i < m_in_ports.size(); i++) { - if (m_in_ports[i]->getCode().find("mandatoryQueue_ptr")!= string::npos) - has_mandatory_q = true; - } - - out << "int " << component << "_Controller::getNumControllers() {" << endl; - out << " return m_num_controllers;" << endl; - out << "}" << endl; - - out << endl; - - out << "MessageBuffer* " << component << "_Controller::getMandatoryQueue() const {" << endl; - if (has_mandatory_q) - out << " return m_" << component << "_mandatoryQueue_ptr;" << endl; - else - out << " return NULL;" << endl; - out << "}" << endl; - - out << endl; - - out << "const int & "<<component<<"_Controller::getVersion() const{" << endl; - out << " return m_version;" << endl; - out << "}"; - - out << endl; - - out << "const string "<<component<<"_Controller::toString() const{" << endl; - out << " return \"" << component<< "_Controller\";" << endl; - out << "}"; - - out << endl; - - out << "const string "<<component<<"_Controller::getName() const{" << endl; - out << " return m_name;" << endl; - out << "}"; - - out << endl; - - out << "const MachineType "<<component<<"_Controller::getMachineType() const{" << endl; - out << " return MachineType_" << component<< ";" << endl; - out << "}"; - - out << endl; - - out << "void " << component << "_Controller::print(ostream& out) const { out << \"[" << component - << "_Controller \" << m_version << \"]\"; }" << endl; - - out << "void " << component << "_Controller::printConfig(ostream& out) const {" << endl; - out << " out << \"" << component << "_Controller config: \" << m_name << endl;" << endl; - out << " out << \" version: \" << m_version << endl;" << endl; - out << " for(map< string, string >::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) {" << endl; - out << " out << \" \" << (*it).first << \": \" << (*it).second << endl;" << endl; - out << " }" << endl; - out << "}" << endl; - - out << endl; - out << "// Actions" << endl; - out << endl; - - for(int i=0; i < numActions(); i++) { - const Action& action = getAction(i); - if (action.existPair("c_code")) { - out << "/** \\brief " << action.getDescription() << "*/" << endl; - out << "void " << component << "_Controller::" - << action.getIdent() << "(const Address& addr)" << endl; - out << "{" << endl; - out << " DEBUG_MSG(GENERATED_COMP, HighPrio,\"executing\");" << endl; -//added by SS -//it should point to m_latency... -//so I should change the string output of this lookup - - - string c_code_string = action.lookupPair("c_code"); - - out << c_code_string; - - out << "}" << endl; - } - out << endl; - } -} - -void StateMachine::printCWakeup(ostream& out, string component) -{ - out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << "// " << getIdent() << ": " << getShorthand() << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; - out << "#include \"mem/protocol/Types.hh\"" << endl; - out << "#include \"mem/ruby/system/System.hh\"" << endl; - out << endl; - out << "void " << component << "_Controller::wakeup()" << endl; - out << "{" << endl; - // out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,*this);" << endl; - // out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,g_eventQueue_ptr->getTime());" << endl; - out << endl; - out << "int counter = 0;" << endl; - out << " while (true) {" << endl; - out << " // Some cases will put us into an infinite loop without this limit" << endl; - out << " assert(counter <= m_transitions_per_cycle);" << endl; - out << " if (counter == m_transitions_per_cycle) {" << endl; - out << " g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we're fully utilized" << endl; - out << " g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again" << endl; - out << " break;" << endl; - out << " }" << endl; - - // InPorts - // - // Find the position of the mandatory queue in the vector so that we can print it out first - int j = -1; - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - for(int i=0; i < m_in_ports.size(); i++) { - const Var* port = m_in_ports[i]; - assert(port->existPair("c_code_in_port")); - if (port->toString().find("mandatoryQueue_in") != string::npos) { - assert (j == -1); - j = i; - } - else { - cout << port->toString() << endl << flush; - } - } - - assert(j != -1); - - // print out the mandatory queue here - const Var* port = m_in_ports[j]; - assert(port->existPair("c_code_in_port")); - out << " // " - << component << "InPort " << port->toString() - << endl; - string output = port->lookupPair("c_code_in_port"); - - out << output; - out << endl; - } - for(int i=0; i < m_in_ports.size(); i++) { - const Var* port = m_in_ports[i]; - // don't print out mandatory queue twice - if (i != j) { - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - if (port->toString().find("forwardRequestNetwork_in") != string::npos) { - out << " bool postpone = false;" << endl; - out << " if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) {" << endl; - out << " const RequestMsg* in_msg_ptr;" << endl; - out << " in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_forwardToCache_ptr)).peek());" << endl; - out << " if ((((servicing_atomic > 0) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) {" << endl; - out << " postpone = true;" << endl; - out << " }" << endl; - - out << " }" << endl; - out << " if (!postpone) {" << endl; - } - else if (port->toString().find("requestNetwork_in") != string::npos || port->toString().find("requestIntraChipL1Network_in") != string::npos) { - out << " bool postpone = false;" << endl; - out << " if ((((*m_L1Cache_requestToL1Cache_ptr)).isReady())) {" << endl; - out << " const RequestMsg* in_msg_ptr;" << endl; - out << " in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_requestToL1Cache_ptr)).peek());" << endl; - out << " if ((((servicing_atomic > 0) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) {" << endl; - out << " postpone = true;" << endl; - out << " }" << endl; - - out << " }" << endl; - out << " if (!postpone) {" << endl; - } - } - assert(port->existPair("c_code_in_port")); - out << " // " - << component << "InPort " << port->toString() - << endl; - out << port->lookupPair("c_code_in_port"); - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - if (port->toString().find("forwardRequestNetwork_in") != string::npos) { - out << "}" << endl; - } - else if (port->toString().find("requestIntraChipL1Network_in") != string::npos) { - out << "}" << endl; - } - else if (port->toString().find("requestNetwork_in") != string::npos) { - out << "}" << endl; - } - } - out << endl; - } - } - - out << " break; // If we got this far, we have nothing left todo" << endl; - out << " }" << endl; - // out << " g_eventQueue_ptr->scheduleEvent(this, 1);" << endl; - // out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; - out << "}" << endl; - out << endl; - - - // tack on two more functions - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - out << "void " << component << "_Controller::set_atomic(Address addr)" << endl; - out << "{" << endl; - out << " servicing_atomic++; " << endl; - out << " switch (servicing_atomic) { " << endl; - out << " case(1): " << endl; - out << " assert(locked_read_request1 == Address(-1)); " << endl; - out << " locked_read_request1 = addr; " << endl; - out << " break; " << endl; - out << " case(2): " << endl; - out << " assert(locked_read_request2 == Address(-1)); " << endl; - out << " locked_read_request2 = addr; " << endl; - out << " break; " << endl; - out << " case(3): " << endl; - out << " assert(locked_read_request3 == Address(-1)); " << endl; - out << " locked_read_request3 = addr; " << endl; - out << " break; " << endl; - out << " case(4): " << endl; - out << " assert(locked_read_request4 == Address(-1)); " << endl; - out << " locked_read_request4 = addr; " << endl; - out << " break; " << endl; - out << " default: " << endl; - out << " assert(0);" << endl; - out << " }" << endl; - out << "}" << endl; - - out << "void " << component << "_Controller::clear_atomic(Address addr)" << endl; - out << "{" << endl; - out << " assert(servicing_atomic > 0); " << endl; - out << " if (addr == locked_read_request1) " << endl; - out << " locked_read_request1 = Address(-1);" << endl; - out << " else if (addr == locked_read_request2)" << endl; - out << " locked_read_request2 = Address(-1);" << endl; - out << " else if (addr == locked_read_request3)" << endl; - out << " locked_read_request3 = Address(-1);" << endl; - out << " else if (addr == locked_read_request4)" << endl; - out << " locked_read_request4 = Address(-1);" << endl; - out << " else " << endl; - out << " assert(0); " << endl; - out << " servicing_atomic--; " << endl; - out << "}" << endl; - - out << "void " << component << "_Controller::reset_atomics()" << endl; - out << "{" << endl; - out << " servicing_atomic = 0; " << endl; - out << " locked_read_request1 = Address(-1);" << endl; - out << " locked_read_request2 = Address(-1);" << endl; - out << " locked_read_request3 = Address(-1);" << endl; - out << " locked_read_request4 = Address(-1);" << endl; - out << "}" << endl; - } - else { - out << "void " << component << "_Controller::set_atomic(Address addr)" << endl; - out << "{" << endl; - out << " assert(0); " << endl; - out << "}" << endl; - - out << "void " << component << "_Controller::clear_atomic(Address addr)" << endl; - out << "{" << endl; - out << " assert(0); " << endl; - out << "}" << endl; - - out << "void " << component << "_Controller::reset_atomics()" << endl; - out << "{" << endl; - out << " assert(0); " << endl; - out << "}" << endl; - } - -} - -void StateMachine::printCSwitch(ostream& out, string component) -{ - out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << "// " << getIdent() << ": " << getShorthand() << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; - out << "#include \"mem/protocol/Types.hh\"" << endl; - out << "#include \"mem/ruby/system/System.hh\"" << endl; - out << endl; - out << "#define HASH_FUN(state, event) ((int(state)*" << component - << "_Event_NUM)+int(event))" << endl; - out << endl; - out << "#define GET_TRANSITION_COMMENT() (" << component << "_" << "transitionComment.str())" << endl; - out << "#define CLEAR_TRANSITION_COMMENT() (" << component << "_" << "transitionComment.str(\"\"))" << endl; - out << endl; - out << "TransitionResult " << component << "_Controller::doTransition(" - << component << "_Event event, " - << component << "_State state, " - << "const Address& addr" << endl; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", int priority"; - } - out << ")" << endl; - - out << "{" << endl; - out << " " << component << "_State next_state = state;" << endl; - out << endl; - out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; - out << " DEBUG_MSG(GENERATED_COMP, MedPrio,*this);" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,g_eventQueue_ptr->getTime());" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,state);" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,event);" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,addr);" << endl; - out << endl; - out << " TransitionResult result = doTransitionWorker(event, state, next_state, addr"; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", priority"; - } - out << ");" << endl; - out << endl; - out << " if (result == TransitionResult_Valid) {" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state);" << endl; - out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; - out << " s_profiler.countTransition(state, event);" << endl; - out << " if (Debug::getProtocolTrace()) {" << endl - << " g_system_ptr->getProfiler()->profileTransition(\"" << component - << "\", m_version, addr, " << endl - << " " << component << "_State_to_string(state), " << endl - << " " << component << "_Event_to_string(event), " << endl - << " " << component << "_State_to_string(next_state), GET_TRANSITION_COMMENT());" << endl - << " }" << endl; - out << " CLEAR_TRANSITION_COMMENT();" << endl; - out << " " << component << "_setState(addr, next_state);" << endl; - out << " " << endl; - out << " } else if (result == TransitionResult_ResourceStall) {" << endl; - out << " if (Debug::getProtocolTrace()) {" << endl - << " g_system_ptr->getProfiler()->profileTransition(\"" << component - << "\", m_version, addr, " << endl - << " " << component << "_State_to_string(state), " << endl - << " " << component << "_Event_to_string(event), " << endl - << " " << component << "_State_to_string(next_state), " << endl - << " \"Resource Stall\");" << endl - << " }" << endl; - out << " } else if (result == TransitionResult_ProtocolStall) {" << endl; - out << " DEBUG_MSG(GENERATED_COMP,HighPrio,\"stalling\");" << endl - << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; - out << " if (Debug::getProtocolTrace()) {" << endl - << " g_system_ptr->getProfiler()->profileTransition(\"" << component - << "\", m_version, addr, " << endl - << " " << component << "_State_to_string(state), " << endl - << " " << component << "_Event_to_string(event), " << endl - << " " << component << "_State_to_string(next_state), " << endl - << " \"Protocol Stall\");" << endl - << " }" << endl - << " }" << endl; - out << " return result;" << endl; - out << "}" << endl; - out << endl; - out << "TransitionResult " << component << "_Controller::doTransitionWorker(" - << component << "_Event event, " - << component << "_State state, " - << component << "_State& next_state, " - << "const Address& addr" << endl; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", int priority" << endl; - } - out << ")" << endl; - - out << "{" << endl; - out << "" << endl; - - out << " switch(HASH_FUN(state, event)) {" << endl; - - Map<string, Vector<string> > code_map; // This map will allow suppress generating duplicate code - Vector<string> code_vec; - - for(int i=0; i<numTransitions(); i++) { - const Transition& t = getTransition(i); - string case_string = component + "_State_" + t.getStatePtr()->getIdent() - + ", " + component + "_Event_" + t.getEventPtr()->getIdent(); - - string code; - - code += " {\n"; - // Only set next_state if it changes - if (t.getStatePtr() != t.getNextStatePtr()) { - code += " next_state = " + component + "_State_" + t.getNextStatePtr()->getIdent() + ";\n"; - } - - const Vector<Action*>& action_vec = t.getActions(); - int numActions = action_vec.size(); - - // Check for resources - Vector<string> code_sorter; - const Map<Var*, string>& res = t.getResources(); - Vector<Var*> res_keys = res.keys(); - for (int i=0; i<res_keys.size(); i++) { - string temp_code; - if (res_keys[i]->getType()->cIdent() == "DNUCAStopTable") { - temp_code += res.lookup(res_keys[i]); - } else { - temp_code += " if (!" + (res_keys[i]->getCode()) + ".areNSlotsAvailable(" + res.lookup(res_keys[i]) + ")) {\n"; - if(CHECK_INVALID_RESOURCE_STALLS) { - // assert that the resource stall is for a resource of equal or greater priority - temp_code += " assert(priority >= "+ (res_keys[i]->getCode()) + ".getPriority());\n"; - } - temp_code += " return TransitionResult_ResourceStall;\n"; - temp_code += " }\n"; - } - code_sorter.insertAtBottom(temp_code); - } - - // Emit the code sequences in a sorted order. This makes the - // output deterministic (without this the output order can vary - // since Map's keys() on a vector of pointers is not deterministic - code_sorter.sortVector(); - for (int i=0; i<code_sorter.size(); i++) { - code += code_sorter[i]; - } - - // Figure out if we stall - bool stall = false; - for (int i=0; i<numActions; i++) { - if(action_vec[i]->getIdent() == "z_stall") { - stall = true; - } - } - - if (stall) { - code += " return TransitionResult_ProtocolStall;\n"; - } else { - for (int i=0; i<numActions; i++) { - code += " " + action_vec[i]->getIdent() + "(addr);\n"; - } - code += " return TransitionResult_Valid;\n"; - } - code += " }\n"; - - - // Look to see if this transition code is unique. - if (code_map.exist(code)) { - code_map.lookup(code).insertAtBottom(case_string); - } else { - Vector<string> vec; - vec.insertAtBottom(case_string); - code_map.add(code, vec); - code_vec.insertAtBottom(code); - } - } - - // Walk through all of the unique code blocks and spit out the - // corresponding case statement elements - for (int i=0; i<code_vec.size(); i++) { - string code = code_vec[i]; - - // Iterative over all the multiple transitions that share the same code - for (int case_num=0; case_num<code_map.lookup(code).size(); case_num++) { - string case_string = code_map.lookup(code)[case_num]; - out << " case HASH_FUN(" << case_string << "):" << endl; - } - out << code; - } - - out << " default:" << endl; - out << " WARN_EXPR(m_version);" << endl; - out << " WARN_EXPR(g_eventQueue_ptr->getTime());" << endl; - out << " WARN_EXPR(addr);" << endl; - out << " WARN_EXPR(event);" << endl; - out << " WARN_EXPR(state);" << endl; - out << " ERROR_MSG(\"Invalid transition\");" << endl; - out << " }" << endl; - out << " return TransitionResult_Valid;" << endl; - out << "}" << endl; -} - -void StateMachine::printProfilerH(ostream& out, string component) -{ - out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << "// " << getIdent() << ": " << getShorthand() << endl; - out << endl; - out << "#ifndef " << component << "_PROFILER_H" << endl; - out << "#define " << component << "_PROFILER_H" << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; - out << endl; - out << "class " << component << "_Profiler {" << endl; - out << "public:" << endl; - out << " " << component << "_Profiler();" << endl; - out << " void setVersion(int version);" << endl; - out << " void countTransition(" << component << "_State state, " << component << "_Event event);" << endl; - out << " void possibleTransition(" << component << "_State state, " << component << "_Event event);" << endl; - out << " void dumpStats(ostream& out) const;" << endl; - out << " void clearStats();" << endl; - out << "private:" << endl; - out << " int m_counters[" << component << "_State_NUM][" << component << "_Event_NUM];" << endl; - out << " int m_event_counters[" << component << "_Event_NUM];" << endl; - out << " bool m_possible[" << component << "_State_NUM][" << component << "_Event_NUM];" << endl; - out << " int m_version;" << endl; - out << "};" << endl; - out << "#endif // " << component << "_PROFILER_H" << endl; -} - -void StateMachine::printProfilerC(ostream& out, string component) -{ - out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << "// " << getIdent() << ": " << getShorthand() << endl; - out << endl; - out << "#include \"mem/protocol/" << component << "_Profiler.hh\"" << endl; - out << endl; - - // Constructor - out << component << "_Profiler::" << component << "_Profiler()" << endl; - out << "{" << endl; - out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " m_possible[state][event] = false;" << endl; - out << " m_counters[state][event] = 0;" << endl; - out << " }" << endl; - out << " }" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " m_event_counters[event] = 0;" << endl; - out << " }" << endl; - out << "}" << endl; - - // setVersion - out << "void " << component << "_Profiler::setVersion(int version)" << endl; - out << "{" << endl; - out << " m_version = version;" << endl; - out << "}" << endl; - - // Clearstats - out << "void " << component << "_Profiler::clearStats()" << endl; - out << "{" << endl; - out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " m_counters[state][event] = 0;" << endl; - out << " }" << endl; - out << " }" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " m_event_counters[event] = 0;" << endl; - out << " }" << endl; - out << "}" << endl; - - // Count Transition - out << "void " << component << "_Profiler::countTransition(" << component << "_State state, " << component << "_Event event)" << endl; - out << "{" << endl; - out << " assert(m_possible[state][event]);" << endl; - out << " m_counters[state][event]++;" << endl; - out << " m_event_counters[event]++;" << endl; - out << "}" << endl; - - // Possible Transition - out << "void " << component << "_Profiler::possibleTransition(" << component << "_State state, " << component << "_Event event)" << endl; - out << "{" << endl; - out << " m_possible[state][event] = true;" << endl; - out << "}" << endl; - - // dumpStats - out << "void " << component << "_Profiler::dumpStats(ostream& out) const" << endl; - out << "{" << endl; - out << " out << \" --- " << component << " \" << m_version << \" ---\" << endl;" << endl; - out << " out << \" - Event Counts -\" << endl;" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " int count = m_event_counters[event];" << endl; - out << " out << (" << component << "_Event) event << \" \" << count << endl;" << endl; - out << " }" << endl; - out << " out << endl;" << endl; - out << " out << \" - Transitions -\" << endl;" << endl; - out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " if (m_possible[state][event]) {" << endl; - out << " int count = m_counters[state][event];" << endl; - out << " out << (" << component << "_State) state << \" \" << (" << component << "_Event) event << \" \" << count;" << endl; - out << " if (count == 0) {" << endl; - out << " out << \" <-- \";" << endl; - out << " }" << endl; - out << " out << endl;" << endl; - out << " }" << endl; - out << " }" << endl; - out << " out << endl;" << endl; - out << " }" << endl; - out << "}" << endl; -} - - - -// ************************** // -// ******* HTML Files ******* // -// ************************** // - -string frameRef(string click_href, string click_target, string over_href, string over_target_num, string text) -{ - string temp; - temp += "<A href=\"" + click_href + "\" "; - temp += "target=\"" + click_target + "\" "; - string javascript = "if (parent.frames[" + over_target_num + "].location != parent.location + '" + over_href + "') { parent.frames[" + over_target_num + "].location='" + over_href + "' }"; - // string javascript = "parent." + target + ".location='" + href + "'"; - temp += "onMouseOver=\"" + javascript + "\" "; - temp += ">" + text + "</A>"; - return temp; -} - -string frameRef(string href, string target, string target_num, string text) -{ - return frameRef(href, target, href, target_num, text); -} - - -void StateMachine::writeHTMLFiles(string path) -{ - string filename; - string component = getIdent(); - - /* - { - ostringstream out; - out << "<html>" << endl; - out << "<head>" << endl; - out << "<title>" << component << "</title>" << endl; - out << "</head>" << endl; - out << "<frameset rows=\"30,30,*\" frameborder=\"1\">" << endl; - out << " <frame name=\"Status\" src=\"empty.html\" marginheight=\"1\">" << endl; - out << " <frame name=\"Table\" src=\"" << component << "_table.html\" marginheight=\"1\">" << endl; - out << "</frameset>" << endl; - out << "</html>" << endl; - conditionally_write_file(path + component + ".html", out); - } - */ - - // Create table with no row hilighted - { - ostringstream out; - printHTMLTransitions(out, numStates()+1); - - // -- Write file - filename = component + "_table.html"; - conditionally_write_file(path + filename, out); - } - - // Generate transition tables - for(int i=0; i<numStates(); i++) { - ostringstream out; - printHTMLTransitions(out, i); - - // -- Write file - filename = component + "_table_" + getState(i).getIdent() + ".html"; - conditionally_write_file(path + filename, out); - } - - // Generate action descriptions - for(int i=0; i<numActions(); i++) { - ostringstream out; - createHTMLSymbol(getAction(i), "Action", out); - - // -- Write file - filename = component + "_action_" + getAction(i).getIdent() + ".html"; - conditionally_write_file(path + filename, out); - } - - // Generate state descriptions - for(int i=0; i<numStates(); i++) { - ostringstream out; - createHTMLSymbol(getState(i), "State", out); - - // -- Write file - filename = component + "_State_" + getState(i).getIdent() + ".html"; - conditionally_write_file(path + filename, out); - } - - // Generate event descriptions - for(int i=0; i<numEvents(); i++) { - ostringstream out; - createHTMLSymbol(getEvent(i), "Event", out); - - // -- Write file - filename = component + "_Event_" + getEvent(i).getIdent() + ".html"; - conditionally_write_file(path + filename, out); - } -} - -void StateMachine::printHTMLTransitions(ostream& out, int active_state) -{ - // -- Prolog - out << "<HTML><BODY link=\"blue\" vlink=\"blue\">" << endl; - - // -- Header - out << "<H1 align=\"center\">" << formatHTMLShorthand(getShorthand()) << ": " << endl; - Vector<StateMachine*> machine_vec = g_sym_table.getStateMachines(); - for (int i=0; i<machine_vec.size(); i++) { - StateMachine* type = machine_vec[i]; - if (i != 0) { - out << " - "; - } - if (type == this) { - out << type->getIdent() << endl; - } else { - out << "<A target=\"Table\"href=\"" + type->getIdent() + "_table.html\">" + type->getIdent() + "</A> " << endl; - } - } - out << "</H1>" << endl; - - // -- Table header - out << "<TABLE border=1>" << endl; - - // -- Column headers - out << "<TR>" << endl; - - // -- First column header - out << " <TH> </TH>" << endl; - - for(int event = 0; event < numEvents(); event++ ) { - out << " <TH bgcolor=white>"; - out << frameRef(getIdent() + "_Event_" + getEvent(event).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(event).getShorthand())); - out << "</TH>" << endl; - } - - out << "</TR>" << endl; - - // -- Body of table - for(int state = 0; state < numStates(); state++ ) { - out << "<TR>" << endl; - - // -- Each row - if (state == active_state) { - out << " <TH bgcolor=yellow>"; - } else { - out << " <TH bgcolor=white>"; - } - - string click_href = getIdent() + "_table_" + getState(state).getIdent() + ".html"; - string text = formatHTMLShorthand(getState(state).getShorthand()); - - out << frameRef(click_href, "Table", getIdent() + "_State_" + getState(state).getIdent() + ".html", "1", formatHTMLShorthand(getState(state).getShorthand())); - out << "</TH>" << endl; - - // -- One column for each event - for(int event = 0; event < numEvents(); event++ ) { - const Transition* trans_ptr = getTransPtr(state, event); - - if( trans_ptr != NULL ) { - bool stall_action = false; - string nextState; - string actions_str; - - // -- Get the actions - // actions = trans_ptr->getActionShorthands(); - const Vector<Action*> actions = trans_ptr->getActions(); - for (int action=0; action < actions.size(); action++) { - if ((actions[action]->getIdent() == "z_stall") || - (actions[action]->getIdent() == "zz_recycleMandatoryQueue")) { - stall_action = true; - } - actions_str += " "; - actions_str += frameRef(getIdent() + "_action_" + actions[action]->getIdent() + ".html", "Status", "1", - formatHTMLShorthand(actions[action]->getShorthand())); - actions_str += "\n"; - } - - // -- Get the next state - if (trans_ptr->getNextStatePtr()->getIdent() != getState(state).getIdent()) { - string click_href = getIdent() + "_table_" + trans_ptr->getNextStatePtr()->getIdent() + ".html"; - nextState = frameRef(click_href, "Table", getIdent() + "_State_" + trans_ptr->getNextStatePtr()->getIdent() + ".html", "1", - formatHTMLShorthand(trans_ptr->getNextStateShorthand())); - } else { - nextState = ""; - } - - // -- Print out "actions/next-state" - if (stall_action) { - if (state == active_state) { - out << " <TD bgcolor=#C0C000>"; - } else { - out << " <TD bgcolor=lightgrey>"; - } - } else if (active_state < numStates() && (trans_ptr->getNextStatePtr()->getIdent() == getState(active_state).getIdent())) { - out << " <TD bgcolor=aqua>"; - } else if (state == active_state) { - out << " <TD bgcolor=yellow>"; - } else { - out << " <TD bgcolor=white>"; - } - - out << actions_str; - if ((nextState.length() != 0) && (actions_str.length() != 0)) { - out << "/"; - } - out << nextState; - out << "</TD>" << endl; - } else { - // This is the no transition case - if (state == active_state) { - out << " <TD bgcolor=#C0C000> </TD>" << endl; - } else { - out << " <TD bgcolor=lightgrey> </TD>" << endl; - } - } - } - // -- Each row - if (state == active_state) { - out << " <TH bgcolor=yellow>"; - } else { - out << " <TH bgcolor=white>"; - } - - click_href = getIdent() + "_table_" + getState(state).getIdent() + ".html"; - text = formatHTMLShorthand(getState(state).getShorthand()); - - out << frameRef(click_href, "Table", getIdent() + "_State_" + getState(state).getIdent() + ".html", "1", formatHTMLShorthand(getState(state).getShorthand())); - out << "</TH>" << endl; - - out << "</TR>" << endl; - } - - // -- Column footer - out << "<TR>" << endl; - out << " <TH> </TH>" << endl; - - for(int i = 0; i < numEvents(); i++ ) { - out << " <TH bgcolor=white>"; - out << frameRef(getIdent() + "_Event_" + getEvent(i).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(i).getShorthand())); - out << "</TH>" << endl; - } - out << "</TR>" << endl; - - // -- Epilog - out << "</TABLE>" << endl; - out << "</BODY></HTML>" << endl; -} - - diff --git a/src/mem/slicc/symbols/StateMachine.hh b/src/mem/slicc/symbols/StateMachine.hh deleted file mode 100644 index f5f3ab073..000000000 --- a/src/mem/slicc/symbols/StateMachine.hh +++ /dev/null @@ -1,156 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#ifndef STATEMACHINE_H -#define STATEMACHINE_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Vector.hh" -#include "mem/gems_common/Map.hh" -#include "mem/slicc/symbols/Symbol.hh" -#include <list> - -using namespace std; - -class Transition; -class Event; -class State; -class Action; -class Var; -class Func; -class FormalParamAST; - -class StateMachine : public Symbol { -public: - // Constructors - StateMachine(string ident, const Location& location, const Map<string, string>& pairs, Vector<FormalParamAST*>* config_parameters); - - // Destructor - ~StateMachine(); - - // Public Methods - - // Add items to the state machine - // void setMachine(string ident, const Map<string, string>& pairs); - void addState(State* state_ptr); - void addEvent(Event* event_ptr); - void addAction(Action* action_ptr); - void addTransition(Transition* trans_ptr); - void addInPort(Var* var) { m_in_ports.insertAtBottom(var); } - void addFunc(Func* func); - void addObj(Var* obj) { m_objs.insertAtBottom(obj); } - - // Accessors to vectors - const State& getState(int index) const { return *m_states[index]; } - const Event& getEvent(int index) const { return *m_events[index]; } - const Action& getAction(int index) const { return *m_actions[index]; } - const Transition& getTransition(int index) const { return *m_transitions[index]; } - const Transition* getTransPtr(int stateIndex, int eventIndex) const; - const Var& getObject(int index) const { return *m_objs[index]; } - - // Accessors for size of vectors - int numStates() const { return m_states.size(); } - int numEvents() const { return m_events.size(); } - int numActions() const { return m_actions.size(); } - int numTransitions() const { return m_transitions.size(); } - int numObjects() const { return m_objs.size(); } - - void buildTable(); // Needs to be called before accessing the table - - // Code generator methods - void writeCFiles(string path) ; - void writeHTMLFiles(string path) ; - - void print(ostream& out) const { out << "[StateMachine: " << toString() << "]" << endl; } -private: - - Vector<FormalParamAST*>* m_config_parameters; - - // Private Methods - void checkForDuplicate(const Symbol& sym) const; - - int getStateIndex(State* state_ptr) const { return m_state_map.lookup(state_ptr); } - int getEventIndex(Event* event_ptr) const { return m_event_map.lookup(event_ptr); } - - // Private copy constructor and assignment operator - // StateMachine(const StateMachine& obj); - // StateMachine& operator=(const StateMachine& obj); - - void printControllerH(ostream& out, string component) ; - void printControllerC(ostream& out, string component) ; - void printCWakeup(ostream& out, string component) ; - void printCSwitch(ostream& out, string component) ; - void printProfilerH(ostream& out, string component) ; - void printProfilerC(ostream& out, string component) ; - - void printHTMLTransitions(ostream& out, int active_state) ; - - // Data Members (m_ prefix) - Vector<State*> m_states; - Vector<Event*> m_events; - Vector<Action*> m_actions; - Vector<Transition*> m_transitions; - Vector<Func*> m_internal_func_vec; - - Map<State*, int> m_state_map; - Map<Event*, int> m_event_map; - - Vector<Var*> m_in_ports; - - Vector<Var*> m_objs; - - // Table variables - bool m_table_built; - Vector<Vector<Transition*> > m_table; - - //added by SS - std::vector<std::string> m_message_buffer_names; - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const StateMachine& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const StateMachine& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //STATEMACHINE_H diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py new file mode 100644 index 000000000..af9850896 --- /dev/null +++ b/src/mem/slicc/symbols/StateMachine.py @@ -0,0 +1,1164 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter, orderdict + +from slicc.symbols.Symbol import Symbol +from slicc.symbols.Var import Var +import slicc.generate.html as html + +class StateMachine(Symbol): + def __init__(self, symtab, ident, location, pairs, config_parameters): + super(StateMachine, self).__init__(symtab, ident, location, pairs) + self.table = None + self.config_parameters = config_parameters + for param in config_parameters: + var = Var(symtab, param.name, location, param.type_ast.type, + "m_%s" % param.name, {}, self) + self.symtab.registerSym(param.name, var) + + self.states = orderdict() + self.events = orderdict() + self.actions = orderdict() + self.transitions = [] + self.in_ports = [] + self.functions = [] + self.objects = [] + + self.message_buffer_names = [] + + def __repr__(self): + return "[StateMachine: %s]" % self.ident + + def addState(self, state): + assert self.table is None + self.states[state.ident] = state + + def addEvent(self, event): + assert self.table is None + self.events[event.ident] = event + + def addAction(self, action): + assert self.table is None + + # Check for duplicate action + for other in self.actions.itervalues(): + if action.ident == other.ident: + action.warning("Duplicate action definition: %s" % action.ident) + action.error("Duplicate action definition: %s" % action.ident) + if action.short == other.short: + other.warning("Duplicate action shorthand: %s" % other.ident) + other.warning(" shorthand = %s" % other.short) + action.warning("Duplicate action shorthand: %s" % action.ident) + action.error(" shorthand = %s" % action.short) + + self.actions[action.ident] = action + + def addTransition(self, trans): + assert self.table is None + self.transitions.append(trans) + + def addInPort(self, var): + self.in_ports.append(var) + + def addFunc(self, func): + # register func in the symbol table + self.symtab.registerSym(str(func), func) + self.functions.append(func) + + def addObject(self, obj): + self.objects.append(obj) + + # Needs to be called before accessing the table + def buildTable(self): + assert self.table is None + + table = {} + + for trans in self.transitions: + # Track which actions we touch so we know if we use them + # all -- really this should be done for all symbols as + # part of the symbol table, then only trigger it for + # Actions, States, Events, etc. + + for action in trans.actions: + action.used = True + + index = (trans.state, trans.event) + if index in table: + table[index].warning("Duplicate transition: %s" % table[index]) + trans.error("Duplicate transition: %s" % trans) + table[index] = trans + + # Look at all actions to make sure we used them all + for action in self.actions.itervalues(): + if not action.used: + error_msg = "Unused action: %s" % action.ident + if "desc" in action: + error_msg += ", " + action.desc + action.warning(error_msg) + self.table = table + + def writeCodeFiles(self, path): + self.printControllerHH(path) + self.printControllerCC(path) + self.printCSwitch(path) + self.printCWakeup(path) + self.printProfilerCC(path) + self.printProfilerHH(path) + + for func in self.functions: + func.writeCodeFiles(path) + + def printControllerHH(self, path): + '''Output the method declarations for the class declaration''' + code = code_formatter() + ident = self.ident + c_ident = "%s_Controller" % self.ident + + self.message_buffer_names = [] + + code(''' +/** \\file $ident.hh + * + * Auto generated C++ code started by $__file__:$__line__ + * Created by slicc definition of Module "${{self.short}}" + */ + +#ifndef ${ident}_CONTROLLER_H +#define ${ident}_CONTROLLER_H + +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/Consumer.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/protocol/TransitionResult.hh" +#include "mem/protocol/Types.hh" +#include "mem/protocol/${ident}_Profiler.hh" +''') + + seen_types = set() + for var in self.objects: + if var.type.ident not in seen_types and not var.type.isPrimitive: + code('#include "mem/protocol/${{var.type.c_ident}}.hh"') + seen_types.add(var.type.ident) + + # for adding information to the protocol debug trace + code(''' +extern stringstream ${ident}_transitionComment; + +class $c_ident : public AbstractController { +#ifdef CHECK_COHERENCE +#endif /* CHECK_COHERENCE */ +public: + $c_ident(const string & name); + static int getNumControllers(); + void init(Network* net_ptr, const vector<string> & argv); + MessageBuffer* getMandatoryQueue() const; + const int & getVersion() const; + const string toString() const; + const string getName() const; + const MachineType getMachineType() const; + void print(ostream& out) const; + void printConfig(ostream& out) const; + void wakeup(); + void set_atomic(Address addr); + void clear_atomic(Address addr); + void reset_atomics(); + void printStats(ostream& out) const { s_profiler.dumpStats(out); } + void clearStats() { s_profiler.clearStats(); } +private: +''') + + code.indent() + # added by SS + for param in self.config_parameters: + code('int m_${{param.ident}};') + + if self.ident == "L1Cache": + code(''' +int servicing_atomic; +Address locked_read_request1; +Address locked_read_request2; +Address locked_read_request3; +Address locked_read_request4; +int read_counter; +''') + + code(''' +int m_number_of_TBEs; + +TransitionResult doTransition(${ident}_Event event, ${ident}_State state, const Address& addr); // in ${ident}_Transitions.cc +TransitionResult doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr); // in ${ident}_Transitions.cc +string m_name; +int m_transitions_per_cycle; +int m_buffer_size; +int m_recycle_latency; +map< string, string > m_cfg; +NodeID m_version; +Network* m_net_ptr; +MachineID m_machineID; +${ident}_Profiler s_profiler; +static int m_num_controllers; +// Internal functions +''') + + for func in self.functions: + proto = func.prototype + if proto: + code('$proto') + + code(''' + +// Actions +''') + for action in self.actions.itervalues(): + code('/** \\brief ${{action.desc}} */') + code('void ${{action.ident}}(const Address& addr);') + + # the controller internal variables + code(''' + +// Object +''') + for var in self.objects: + th = var.get("template_hack", "") + code('${{var.type.c_ident}}$th* m_${{var.c_ident}}_ptr;') + + if var.type.ident == "MessageBuffer": + self.message_buffer_names.append("m_%s_ptr" % var.c_ident) + + code.dedent() + code('};') + code('#endif // ${ident}_CONTROLLER_H') + code.write(path, '%s.hh' % c_ident) + + def printControllerCC(self, path): + '''Output the actions for performing the actions''' + + code = code_formatter() + ident = self.ident + c_ident = "%s_Controller" % self.ident + + code(''' +/** \\file $ident.cc + * + * Auto generated C++ code started by $__file__:$__line__ + * Created by slicc definition of Module "${{self.short}}" + */ + +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" +#include "mem/protocol/${ident}_Controller.hh" +#include "mem/protocol/${ident}_State.hh" +#include "mem/protocol/${ident}_Event.hh" +#include "mem/protocol/Types.hh" +#include "mem/ruby/system/System.hh" +''') + + # include object classes + seen_types = set() + for var in self.objects: + if var.type.ident not in seen_types and not var.type.isPrimitive: + code('#include "mem/protocol/${{var.type.c_ident}}.hh"') + seen_types.add(var.type.ident) + + code(''' +int $c_ident::m_num_controllers = 0; + +stringstream ${ident}_transitionComment; +#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str) +/** \\brief constructor */ +$c_ident::$c_ident(const string &name) + : m_name(name) +{ +''') + code.indent() + if self.ident == "L1Cache": + code(''' +servicing_atomic = 0; +locked_read_request1 = Address(-1); +locked_read_request2 = Address(-1); +locked_read_request3 = Address(-1); +locked_read_request4 = Address(-1); +read_counter = 0; +''') + + code('m_num_controllers++;') + for var in self.objects: + if var.ident.find("mandatoryQueue") >= 0: + code('m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();') + + code.dedent() + code(''' +} + +void $c_ident::init(Network *net_ptr, const vector<string> &argv) +{ + for (size_t i = 0; i < argv.size(); i += 2) { + if (argv[i] == "version") + m_version = atoi(argv[i+1].c_str()); + else if (argv[i] == "transitions_per_cycle") + m_transitions_per_cycle = atoi(argv[i+1].c_str()); + else if (argv[i] == "buffer_size") + m_buffer_size = atoi(argv[i+1].c_str()); + else if (argv[i] == "recycle_latency") + m_recycle_latency = atoi(argv[i+1].c_str()); + else if (argv[i] == "number_of_TBEs") + m_number_of_TBEs = atoi(argv[i+1].c_str()); +''') + + code.indent() + code.indent() + for param in self.config_parameters: + code('else if (argv[i] == "${{param.name}}")') + if param.type_ast.type.ident == "int": + code(' m_${{param.name}} = atoi(argv[i+1].c_str());') + elif param.type_ast.type.ident == "bool": + code(' m_${{param.name}} = string_to_bool(argv[i+1]);') + else: + self.error("only int and bool parameters are "\ + "currently supported") + code.dedent() + code.dedent() + code(''' + } + + m_net_ptr = net_ptr; + m_machineID.type = MachineType_${ident}; + m_machineID.num = m_version; + for (size_t i = 0; i < argv.size(); i += 2) { + if (argv[i] != "version") + m_cfg[argv[i]] = argv[i+1]; + } + + // Objects + s_profiler.setVersion(m_version); +''') + + code.indent() + for var in self.objects: + vtype = var.type + vid = "m_%s_ptr" % var.c_ident + if "network" not in var: + # Not a network port object + if "primitive" in vtype: + code('$vid = new ${{vtype.c_ident}};') + if "default" in var: + code('(*$vid) = ${{var["default"]}};') + else: + # Normal Object + # added by SS + if "factory" in var: + code('$vid = ${{var["factory"]}};') + elif var.ident.find("mandatoryQueue") < 0: + th = var.get("template_hack", "") + expr = "%s = new %s%s" % (vid, vtype.c_ident, th) + + args = "" + if "non_obj" not in vtype and not vtype.isEnumeration: + if expr.find("TBETable") >= 0: + args = "m_number_of_TBEs" + else: + args = var.get("constructor_hack", "") + args = "(%s)" % args + + code('$expr$args;') + else: + code(';') + + code('assert($vid != NULL);') + + if "default" in var: + code('(*$vid) = ${{var["default"]}}; // Object default') + elif "default" in vtype: + code('(*$vid) = ${{vtype["default"]}}; // Type ${{vtype.ident}} default') + + # Set ordering + if "ordered" in var and "trigger_queue" not in var: + # A buffer + code('$vid->setOrdering(${{var["ordered"]}});') + + # Set randomization + if "random" in var: + # A buffer + code('$vid->setRandomization(${{var["random"]}});') + + # Set Priority + if vtype.isBuffer and \ + "rank" in var and "trigger_queue" not in var: + code('$vid->setPriority(${{var["rank"]}});') + else: + # Network port object + network = var["network"] + ordered = var["ordered"] + vnet = var["virtual_network"] + + assert var.machine is not None + code(''' +$vid = m_net_ptr->get${network}NetQueue(m_version+MachineType_base_number(string_to_MachineType("${{var.machine.ident}}")), $ordered, $vnet); +''') + + code('assert($vid != NULL);') + + # Set ordering + if "ordered" in var: + # A buffer + code('$vid->setOrdering(${{var["ordered"]}});') + + # Set randomization + if "random" in var: + # A buffer + code('$vid->setRandomization(${{var["random"]}})') + + # Set Priority + if "rank" in var: + code('$vid->setPriority(${{var["rank"]}})') + + # Set buffer size + if vtype.isBuffer: + code(''' +if (m_buffer_size > 0) { + $vid->setSize(m_buffer_size); +} +''') + + # set description (may be overriden later by port def) + code('$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");') + + # Set the queue consumers + code.insert_newline() + for port in self.in_ports: + code('${{port.code}}.setConsumer(this);') + + # Set the queue descriptions + code.insert_newline() + for port in self.in_ports: + code('${{port.code}}.setDescription("[Version " + int_to_string(m_version) + ", $ident, $port]");') + + # Initialize the transition profiling + code.insert_newline() + for trans in self.transitions: + # Figure out if we stall + stall = False + for action in trans.actions: + if action.ident == "z_stall": + stall = True + + # Only possible if it is not a 'z' case + if not stall: + state = "%s_State_%s" % (self.ident, trans.state.ident) + event = "%s_Event_%s" % (self.ident, trans.event.ident) + code('s_profiler.possibleTransition($state, $event);') + + # added by SS to initialize recycle_latency of message buffers + for buf in self.message_buffer_names: + code("$buf->setRecycleLatency(m_recycle_latency);") + + code.dedent() + code('}') + + has_mandatory_q = False + for port in self.in_ports: + if port.code.find("mandatoryQueue_ptr") >= 0: + has_mandatory_q = True + + if has_mandatory_q: + mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident + else: + mq_ident = "NULL" + + code(''' +int $c_ident::getNumControllers() { + return m_num_controllers; +} + +MessageBuffer* $c_ident::getMandatoryQueue() const { + return $mq_ident; +} + +const int & $c_ident::getVersion() const{ + return m_version; +} + +const string $c_ident::toString() const{ + return "$c_ident"; +} + +const string $c_ident::getName() const{ + return m_name; +} +const MachineType $c_ident::getMachineType() const{ + return MachineType_${ident}; +} + +void $c_ident::print(ostream& out) const { out << "[$c_ident " << m_version << "]"; } + +void $c_ident::printConfig(ostream& out) const { + out << "$c_ident config: " << m_name << endl; + out << " version: " << m_version << endl; + for (map<string, string>::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) { + out << " " << (*it).first << ": " << (*it).second << endl; + } +} + +// Actions +''') + + for action in self.actions.itervalues(): + if "c_code" not in action: + continue + + code(''' +/** \\brief ${{action.desc}} */ +void $c_ident::${{action.ident}}(const Address& addr) +{ + DEBUG_MSG(GENERATED_COMP, HighPrio, "executing"); + ${{action["c_code"]}} +} + +''') + code.write(path, "%s.cc" % c_ident) + + def printCWakeup(self, path): + '''Output the wakeup loop for the events''' + + code = code_formatter() + ident = self.ident + + code(''' +// Auto generated C++ code started by $__file__:$__line__ +// ${ident}: ${{self.short}} + +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" +#include "mem/protocol/${ident}_Controller.hh" +#include "mem/protocol/${ident}_State.hh" +#include "mem/protocol/${ident}_Event.hh" +#include "mem/protocol/Types.hh" +#include "mem/ruby/system/System.hh" + +void ${ident}_Controller::wakeup() +{ + + int counter = 0; + while (true) { + // Some cases will put us into an infinite loop without this limit + assert(counter <= m_transitions_per_cycle); + if (counter == m_transitions_per_cycle) { + g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we\'re fully utilized + g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again + break; + } +''') + + code.indent() + code.indent() + + # InPorts + # + # Find the position of the mandatory queue in the vector so + # that we can print it out first + + mandatory_q = None + if self.ident == "L1Cache": + for i,port in enumerate(self.in_ports): + assert "c_code_in_port" in port + if str(port).find("mandatoryQueue_in") >= 0: + assert mandatory_q is None + mandatory_q = port + + assert mandatory_q is not None + + # print out the mandatory queue here + port = mandatory_q + code('// ${ident}InPort $port') + output = port["c_code_in_port"] + + code('$output') + + for port in self.in_ports: + # don't print out mandatory queue twice + if port == mandatory_q: + continue + + if ident == "L1Cache": + if (str(port).find("forwardRequestNetwork_in") >= 0 or str(port).find("requestNetwork_in") >= 0 or str(port).find("requestIntraChipL1Network_in") >= 0): + code(''' +bool postpone = false; +if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) { + const RequestMsg* in_msg_ptr; + in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_forwardToCache_ptr)).peek()); + if ((((servicing_atomic > 0) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) { + postpone = true; + } +} +if (!postpone) { +''') + code.indent() + code('// ${ident}InPort $port') + code('${{port["c_code_in_port"]}}') + code.dedent() + + if ident == "L1Cache": + if (str(port).find("forwardRequestNetwork_in") >= 0 or str(port).find("requestNetwork_in") >= 0 or str(port).find("requestIntraChipL1Network_in") >= 0): + code.dedent() + code('}') + code.indent() + code('') + + code.dedent() + code.dedent() + code(''' + break; // If we got this far, we have nothing left todo + } +} +''') + + if self.ident == "L1Cache": + code(''' +void ${ident}_Controller::set_atomic(Address addr) +{ + servicing_atomic++; + switch (servicing_atomic) { + case(1): + assert(locked_read_request1 == Address(-1)); + locked_read_request1 = addr; + break; + case(2): + assert(locked_read_request2 == Address(-1)); + locked_read_request2 = addr; + break; + case(3): + assert(locked_read_request3 == Address(-1)); + locked_read_request3 = addr; + break; + case(4): + assert(locked_read_request4 == Address(-1)); + locked_read_request4 = addr; + break; + default: + assert(0); + + } +} + +void ${ident}_Controller::clear_atomic(Address addr) +{ + + assert(servicing_atomic > 0); + if (addr == locked_read_request1) + locked_read_request1 = Address(-1); + else if (addr == locked_read_request2) + locked_read_request2 = Address(-1); + else if (addr == locked_read_request3) + locked_read_request3 = Address(-1); + else if (addr == locked_read_request4) + locked_read_request4 = Address(-1); + else + assert(0); + servicing_atomic--; + +} + +void ${ident}_Controller::reset_atomics() +{ + + servicing_atomic = 0; + locked_read_request1 = Address(-1); + locked_read_request2 = Address(-1); + locked_read_request3 = Address(-1); + locked_read_request4 = Address(-1); + +} + +''') + else: + code(''' +void ${ident}_Controller::reset_atomics() +{ + assert(0); +} + +void ${ident}_Controller::set_atomic(Address addr) +{ + assert(0); +} + +void ${ident}_Controller::clear_atomic(Address addr) +{ + assert(0); +} +''') + + + code.write(path, "%s_Wakeup.cc" % self.ident) + + def printCSwitch(self, path): + '''Output switch statement for transition table''' + + code = code_formatter() + ident = self.ident + + code(''' +// Auto generated C++ code started by $__file__:$__line__ +// ${ident}: ${{self.short}} + +#include "mem/ruby/common/Global.hh" +#include "mem/protocol/${ident}_Controller.hh" +#include "mem/protocol/${ident}_State.hh" +#include "mem/protocol/${ident}_Event.hh" +#include "mem/protocol/Types.hh" +#include "mem/ruby/system/System.hh" + +#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event)) + +#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str()) +#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str("")) + +TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident}_State state, const Address& addr +) +{ + ${ident}_State next_state = state; + + DEBUG_NEWLINE(GENERATED_COMP, MedPrio); + DEBUG_MSG(GENERATED_COMP, MedPrio, *this); + DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime()); + DEBUG_EXPR(GENERATED_COMP, MedPrio,state); + DEBUG_EXPR(GENERATED_COMP, MedPrio,event); + DEBUG_EXPR(GENERATED_COMP, MedPrio,addr); + + TransitionResult result = doTransitionWorker(event, state, next_state, addr); + + if (result == TransitionResult_Valid) { + DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state); + DEBUG_NEWLINE(GENERATED_COMP, MedPrio); + s_profiler.countTransition(state, event); + if (Debug::getProtocolTrace()) { + g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, + ${ident}_State_to_string(state), + ${ident}_Event_to_string(event), + ${ident}_State_to_string(next_state), GET_TRANSITION_COMMENT()); + } + CLEAR_TRANSITION_COMMENT(); + ${ident}_setState(addr, next_state); + + } else if (result == TransitionResult_ResourceStall) { + if (Debug::getProtocolTrace()) { + g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, + ${ident}_State_to_string(state), + ${ident}_Event_to_string(event), + ${ident}_State_to_string(next_state), + "Resource Stall"); + } + } else if (result == TransitionResult_ProtocolStall) { + DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling"); + DEBUG_NEWLINE(GENERATED_COMP, MedPrio); + if (Debug::getProtocolTrace()) { + g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, + ${ident}_State_to_string(state), + ${ident}_Event_to_string(event), + ${ident}_State_to_string(next_state), + "Protocol Stall"); + } + } + + return result; +} + +TransitionResult ${ident}_Controller::doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr +) +{ + switch(HASH_FUN(state, event)) { +''') + + # This map will allow suppress generating duplicate code + cases = orderdict() + + for trans in self.transitions: + case_string = "%s_State_%s, %s_Event_%s" % \ + (self.ident, trans.state.ident, self.ident, trans.event.ident) + + case = code_formatter() + # Only set next_state if it changes + if trans.state != trans.nextState: + ns_ident = trans.nextState.ident + case('next_state = ${ident}_State_${ns_ident};') + + actions = trans.actions + + # Check for resources + case_sorter = [] + res = trans.resources + for key,val in res.iteritems(): + if key.type.ident != "DNUCAStopTable": + val = ''' +if (!%s.areNSlotsAvailable(%s)) { + return TransitionResult_ResourceStall; +} +''' % (key.code, val) + case_sorter.append(val) + + + # Emit the code sequences in a sorted order. This makes the + # output deterministic (without this the output order can vary + # since Map's keys() on a vector of pointers is not deterministic + for c in sorted(case_sorter): + case("$c") + + # Figure out if we stall + stall = False + for action in actions: + if action.ident == "z_stall": + stall = True + break + + if stall: + case('return TransitionResult_ProtocolStall;') + else: + for action in actions: + case('${{action.ident}}(addr);') + case('return TransitionResult_Valid;') + + case = str(case) + + # Look to see if this transition code is unique. + if case not in cases: + cases[case] = [] + + cases[case].append(case_string) + + # Walk through all of the unique code blocks and spit out the + # corresponding case statement elements + for case,transitions in cases.iteritems(): + # Iterative over all the multiple transitions that share + # the same code + for trans in transitions: + code(' case HASH_FUN($trans):') + code(' {') + code(' $case') + code(' }') + + code(''' + default: + WARN_EXPR(m_version); + WARN_EXPR(g_eventQueue_ptr->getTime()); + WARN_EXPR(addr); + WARN_EXPR(event); + WARN_EXPR(state); + ERROR_MSG(\"Invalid transition\"); + } + return TransitionResult_Valid; +} +''') + code.write(path, "%s_Transitions.cc" % self.ident) + + def printProfilerHH(self, path): + code = code_formatter() + ident = self.ident + + code(''' +// Auto generated C++ code started by $__file__:$__line__ +// ${ident}: ${{self.short}} + +#ifndef ${ident}_PROFILER_H +#define ${ident}_PROFILER_H + +#include "mem/ruby/common/Global.hh" +#include "mem/protocol/${ident}_State.hh" +#include "mem/protocol/${ident}_Event.hh" + +class ${ident}_Profiler { + public: + ${ident}_Profiler(); + void setVersion(int version); + void countTransition(${ident}_State state, ${ident}_Event event); + void possibleTransition(${ident}_State state, ${ident}_Event event); + void dumpStats(ostream& out) const; + void clearStats(); + + private: + int m_counters[${ident}_State_NUM][${ident}_Event_NUM]; + int m_event_counters[${ident}_Event_NUM]; + bool m_possible[${ident}_State_NUM][${ident}_Event_NUM]; + int m_version; +}; + +#endif // ${ident}_PROFILER_H +''') + code.write(path, "%s_Profiler.hh" % self.ident) + + def printProfilerCC(self, path): + code = code_formatter() + ident = self.ident + + code(''' +// Auto generated C++ code started by $__file__:$__line__ +// ${ident}: ${{self.short}} + +#include "mem/protocol/${ident}_Profiler.hh" + +${ident}_Profiler::${ident}_Profiler() +{ + for (int state = 0; state < ${ident}_State_NUM; state++) { + for (int event = 0; event < ${ident}_Event_NUM; event++) { + m_possible[state][event] = false; + m_counters[state][event] = 0; + } + } + for (int event = 0; event < ${ident}_Event_NUM; event++) { + m_event_counters[event] = 0; + } +} +void ${ident}_Profiler::setVersion(int version) +{ + m_version = version; +} +void ${ident}_Profiler::clearStats() +{ + for (int state = 0; state < ${ident}_State_NUM; state++) { + for (int event = 0; event < ${ident}_Event_NUM; event++) { + m_counters[state][event] = 0; + } + } + + for (int event = 0; event < ${ident}_Event_NUM; event++) { + m_event_counters[event] = 0; + } +} +void ${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event) +{ + assert(m_possible[state][event]); + m_counters[state][event]++; + m_event_counters[event]++; +} +void ${ident}_Profiler::possibleTransition(${ident}_State state, ${ident}_Event event) +{ + m_possible[state][event] = true; +} +void ${ident}_Profiler::dumpStats(ostream& out) const +{ + out << " --- ${ident} " << m_version << " ---" << endl; + out << " - Event Counts -" << endl; + for (int event = 0; event < ${ident}_Event_NUM; event++) { + int count = m_event_counters[event]; + out << (${ident}_Event) event << " " << count << endl; + } + out << endl; + out << " - Transitions -" << endl; + for (int state = 0; state < ${ident}_State_NUM; state++) { + for (int event = 0; event < ${ident}_Event_NUM; event++) { + if (m_possible[state][event]) { + int count = m_counters[state][event]; + out << (${ident}_State) state << " " << (${ident}_Event) event << " " << count; + if (count == 0) { + out << " <-- "; + } + out << endl; + } + } + out << endl; + } +} +''') + code.write(path, "%s_Profiler.cc" % self.ident) + + # ************************** + # ******* HTML Files ******* + # ************************** + def frameRef(self, click_href, click_target, over_href, over_target_num, + text): + code = code_formatter(fix_newlines=False) + code("""<A href=\"$click_href\" target=\"$click_target\" onMouseOver=\"if (parent.frames[$over_target_num].location != parent.location + '$over_href') { parent.frames[$over_target_num].location='$over_href' }\" >${{html.formatShorthand(text)}}</A>""") + return str(code) + + def writeHTMLFiles(self, path): + # Create table with no row hilighted + self.printHTMLTransitions(path, None) + + # Generate transition tables + for state in self.states.itervalues(): + self.printHTMLTransitions(path, state) + + # Generate action descriptions + for action in self.actions.itervalues(): + name = "%s_action_%s.html" % (self.ident, action.ident) + code = html.createSymbol(action, "Action") + code.write(path, name) + + # Generate state descriptions + for state in self.states.itervalues(): + name = "%s_State_%s.html" % (self.ident, state.ident) + code = html.createSymbol(state, "State") + code.write(path, name) + + # Generate event descriptions + for event in self.events.itervalues(): + name = "%s_Event_%s.html" % (self.ident, event.ident) + code = html.createSymbol(event, "Event") + code.write(path, name) + + def printHTMLTransitions(self, path, active_state): + code = code_formatter() + + code(''' +<HTML><BODY link="blue" vlink="blue"> + +<H1 align="center">${{html.formatShorthand(self.short)}}: +''') + code.indent() + for i,machine in enumerate(self.symtab.getAllType(StateMachine)): + mid = machine.ident + if i != 0: + extra = " - " + else: + extra = "" + if machine == self: + code('$extra$mid') + else: + code('$extra<A target="Table" href="${mid}_table.html">$mid</A>') + code.dedent() + + code(""" +</H1> + +<TABLE border=1> +<TR> + <TH> </TH> +""") + + for event in self.events.itervalues(): + href = "%s_Event_%s.html" % (self.ident, event.ident) + ref = self.frameRef(href, "Status", href, "1", event.short) + code('<TH bgcolor=white>$ref</TH>') + + code('</TR>') + # -- Body of table + for state in self.states.itervalues(): + # -- Each row + if state == active_state: + color = "yellow" + else: + color = "white" + + click = "%s_table_%s.html" % (self.ident, state.ident) + over = "%s_State_%s.html" % (self.ident, state.ident) + text = html.formatShorthand(state.short) + ref = self.frameRef(click, "Table", over, "1", state.short) + code(''' +<TR> + <TH bgcolor=$color>$ref</TH> +''') + + # -- One column for each event + for event in self.events.itervalues(): + trans = self.table.get((state,event), None) + if trans is None: + # This is the no transition case + if state == active_state: + color = "#C0C000" + else: + color = "lightgrey" + + code('<TD bgcolor=$color> </TD>') + continue + + next = trans.nextState + stall_action = False + + # -- Get the actions + for action in trans.actions: + if action.ident == "z_stall" or \ + action.ident == "zz_recycleMandatoryQueue": + stall_action = True + + # -- Print out "actions/next-state" + if stall_action: + if state == active_state: + color = "#C0C000" + else: + color = "lightgrey" + + elif active_state and next.ident == active_state.ident: + color = "aqua" + elif state == active_state: + color = "yellow" + else: + color = "white" + + fix = code.nofix() + code('<TD bgcolor=$color>') + for action in trans.actions: + href = "%s_action_%s.html" % (self.ident, action.ident) + ref = self.frameRef(href, "Status", href, "1", + action.short) + code(' $ref\n') + if next != state: + if trans.actions: + code('/') + click = "%s_table_%s.html" % (self.ident, next.ident) + over = "%s_State_%s.html" % (self.ident, next.ident) + ref = self.frameRef(click, "Table", over, "1", next.short) + code("$ref") + code("</TD>\n") + code.fix(fix) + + # -- Each row + if state == active_state: + color = "yellow" + else: + color = "white" + + click = "%s_table_%s.html" % (self.ident, state.ident) + over = "%s_State_%s.html" % (self.ident, state.ident) + ref = self.frameRef(click, "Table", over, "1", state.short) + code(''' + <TH bgcolor=$color>$ref</TH> +</TR> +''') + code(''' +<TR> + <TH> </TH> +''') + + for event in self.events.itervalues(): + href = "%s_Event_%s.html" % (self.ident, event.ident) + ref = self.frameRef(href, "Status", href, "1", event.short) + code('<TH bgcolor=white>$ref</TH>') + code(''' +</TR> +</TABLE> +</BODY></HTML> +''') + + + if active_state: + name = "%s_table_%s.html" % (self.ident, active_state.ident) + else: + name = "%s_table.html" % self.ident + code.write(path, name) + +__all__ = [ "StateMachine" ] diff --git a/src/mem/slicc/symbols/Symbol.hh b/src/mem/slicc/symbols/Symbol.hh deleted file mode 100644 index 4a1c5e44e..000000000 --- a/src/mem/slicc/symbols/Symbol.hh +++ /dev/null @@ -1,100 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -#ifndef SYMBOL_H -#define SYMBOL_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Map.hh" -#include "mem/slicc/ast/Location.hh" - -class Symbol { -public: - // Constructors - Symbol(string id, const Location& location, const Map<string, string>& pairs); - Symbol(string id, const Location& location); - // Destructor - virtual ~Symbol() { } - - // Public Methods - void error(string err_msg) const { m_location.error(err_msg); } - void warning(string err_msg) const { m_location.warning(err_msg); } - const Location& getLocation() const { return m_location; } - - const string& toString() const { return m_id; } - - const string& getIdent() const { return m_id; } - const string& getShorthand() const { return lookupPair("short"); } - const string& getDescription() const { return lookupPair("desc"); } - - void markUsed() { m_used = true; } - bool wasUsed() { return m_used; } - - bool existPair(const string& key) const { return m_pairs.exist(key); } - const string& lookupPair(const string& key) const; - void addPair(const string& key, const string& value); - - // virtual string getCode() const = 0; - virtual void writeCFiles(string path) {} - virtual void writeHTMLFiles(string path) {} - virtual void print(ostream& out) const { out << "[Symbol: " << getIdent() << "]"; } - -private: - // Private Methods - - // Private copy constructor and assignment operator - // Symbol(const Symbol& obj); - // Symbol& operator=(const Symbol& obj); - - // Data Members (m_ prefix) - string m_id; - Map<string, string> m_pairs; - Location m_location; - bool m_used; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Symbol& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Symbol& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //SYMBOL_H diff --git a/src/mem/slicc/symbols/Symbol.py b/src/mem/slicc/symbols/Symbol.py new file mode 100644 index 000000000..b394fda44 --- /dev/null +++ b/src/mem/slicc/symbols/Symbol.py @@ -0,0 +1,78 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.util import PairContainer + +class Symbol(PairContainer): + def __init__(self, symtab, ident, location, pairs=None): + super(Symbol, self).__init__() + + from slicc.util import Location + from slicc.symbols import SymbolTable + if not isinstance(symtab, SymbolTable): raise AttributeError + if not isinstance(ident, str): raise AttributeError + if not isinstance(location, Location): raise AttributeError + + self.symtab = symtab + self.ident = ident + self.location = location + if pairs: + self.pairs.update(getattr(pairs, "pairs", pairs)) + if "short" not in self: + self["short"] = self.ident + self.used = False + + def __repr__(self): + return "[Symbol: %s]" % self.ident + + def __str__(self): + return str(self.ident) + + def __setitem__(self, key, value): + if key in self.pairs: + self.warning("Pair key '%s' re-defined. new: '%s' old: '%s'", + key, value, self.pairs[key]) + super(Symbol, self).__setitem__(key, value) + + @property + def short(self): + return self["short"] + + @property + def desc(self): + return self["desc"] + + def error(self, message, *args): + self.location.error(message, *args) + + def warning(self, message, *args): + self.location.warning(message, *args) + + def writeHTMLFiles(self, path): + pass + +__all__ = [ "Symbol" ] diff --git a/src/mem/slicc/symbols/SymbolTable.cc b/src/mem/slicc/symbols/SymbolTable.cc deleted file mode 100644 index 8af3685f8..000000000 --- a/src/mem/slicc/symbols/SymbolTable.cc +++ /dev/null @@ -1,327 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * SymbolTable.cc - * - * Description: See SymbolTable.hh - * - * $Id$ - * - * */ - -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/generator/html_gen.hh" -#include "mem/slicc/generator/mif_gen.hh" -#include "mem/slicc/symbols/Action.hh" - -SymbolTable g_sym_table; - -SymbolTable::SymbolTable() -{ - m_sym_map_vec.setSize(1); - m_depth = 0; - - { - Map<string, string> pairs; - pairs.add("enumeration", "yes"); - newSym(new Type("MachineType", Location(), pairs)); - } - - { - Map<string, string> pairs; - pairs.add("primitive", "yes"); - pairs.add("external", "yes"); - newSym(new Type("void", Location(), pairs)); - } -} - -SymbolTable::~SymbolTable() -{ - int size = m_sym_vec.size(); - for(int i=0; i<size; i++) { - delete m_sym_vec[i]; - } -} - -void SymbolTable::newSym(Symbol* sym_ptr) -{ - registerSym(sym_ptr->toString(), sym_ptr); - m_sym_vec.insertAtBottom(sym_ptr); // Holder for the allocated Sym objects. -} - -void SymbolTable::newMachComponentSym(Symbol* sym_ptr) -{ - // used to cheat-- that is, access components in other machines - StateMachine* mach_ptr = getStateMachine("current_machine"); - if (mach_ptr != NULL) { - m_machine_component_map_vec.lookup(mach_ptr->toString()).add(sym_ptr->toString(), sym_ptr); - } -} - -Var* SymbolTable::getMachComponentVar(string mach, string ident) -{ - Symbol* s = m_machine_component_map_vec.lookup(mach).lookup(ident); - return dynamic_cast<Var*>(s); -} - - -void SymbolTable::registerSym(string id, Symbol* sym_ptr) -{ - - // Check for redeclaration (in the current frame only) - if (m_sym_map_vec[m_depth].exist(id)) { - sym_ptr->error("Symbol '" + id + "' redeclared in same scope."); - } - // FIXME - warn on masking of a declaration in a previous frame - m_sym_map_vec[m_depth].add(id, sym_ptr); -} - -void SymbolTable::registerGlobalSym(string id, Symbol* sym_ptr) -{ - // Check for redeclaration (global frame only) - if (m_sym_map_vec[0].exist(id)) { - sym_ptr->error("Global symbol '" + id + "' redeclared in global scope."); - } - m_sym_map_vec[0].add(id, sym_ptr); -} - -Symbol* SymbolTable::getSym(string ident) const -{ - for (int i=m_depth; i>=0; i--) { - if (m_sym_map_vec[i].exist(ident)) { - return m_sym_map_vec[i].lookup(ident); - } - } - return NULL; -} - -void SymbolTable::newCurrentMachine(StateMachine* sym_ptr) -{ - registerGlobalSym(sym_ptr->toString(), sym_ptr); - registerSym("current_machine", sym_ptr); - m_sym_vec.insertAtBottom(sym_ptr); // Holder for the allocated Sym objects. - - Map<string, Symbol*> m; - m_machine_component_map_vec.add(sym_ptr->toString(),m); - -} - -Type* SymbolTable::getType(string ident) const -{ - return dynamic_cast<Type*>(getSym(ident)); -} - -Var* SymbolTable::getVar(string ident) const -{ - return dynamic_cast<Var*>(getSym(ident)); -} - -Func* SymbolTable::getFunc(string ident) const -{ - return dynamic_cast<Func*>(getSym(ident)); -} - -StateMachine* SymbolTable::getStateMachine(string ident) const -{ - return dynamic_cast<StateMachine*>(getSym(ident)); -} - -void SymbolTable::pushFrame() -{ - m_depth++; - m_sym_map_vec.expand(1); - m_sym_map_vec[m_depth].clear(); -} - -void SymbolTable::popFrame() -{ - m_depth--; - assert(m_depth >= 0); - m_sym_map_vec.expand(-1); -} - -void SymbolTable::writeCFiles(string path) const -{ - int size = m_sym_vec.size(); - { - // Write the Types.hh include file for the types - ostringstream sstr; - sstr << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl; - sstr << endl; - sstr << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl; - for(int i=0; i<size; i++) { - Type* type = dynamic_cast<Type*>(m_sym_vec[i]); - if (type != NULL && !type->isPrimitive()) { - sstr << "#include \"mem/protocol/" << type->cIdent() << ".hh" << "\"" << endl; - } - } - conditionally_write_file(path + "/Types.hh", sstr); - } - - // Write all the symbols - for(int i=0; i<size; i++) { - m_sym_vec[i]->writeCFiles(path + '/'); - } - - writeControllerFactory(path); -} - -void SymbolTable::writeControllerFactory(string path) const -{ - ostringstream sstr; - int size = m_sym_vec.size(); - - sstr << "/** \\file ControllerFactory.hh " << endl; - sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl; - sstr << " */" << endl << endl; - - sstr << "#ifndef CONTROLLERFACTORY_H" << endl; - sstr << "#define CONTROLLERFACTORY_H" << endl; - sstr << endl; - - Vector< string > controller_types; - - // includes - sstr << "#include <string>" << endl; - sstr << "class Network;" << endl; - sstr << "class AbstractController;" << endl; - sstr << endl; - - sstr << "class ControllerFactory {" << endl; - sstr << "public:" << endl; - sstr << " static AbstractController* createController(const std::string & controller_type, const std::string & name);" << endl; - sstr << "};" << endl; - sstr << endl; - - sstr << "#endif // CONTROLLERFACTORY_H" << endl; - conditionally_write_file(path + "/ControllerFactory.hh", sstr); - - // ControllerFactory.cc file - - sstr.str(""); - - sstr << "/** \\file ControllerFactory.cc " << endl; - sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl; - sstr << " */" << endl << endl; - - // includes - sstr << "#include \"mem/protocol/ControllerFactory.hh\"" << endl; - sstr << "#include \"mem/ruby/slicc_interface/AbstractController.hh\"" << endl; - sstr << "#include \"mem/protocol/MachineType.hh\"" << endl; - for(int i=0; i<size; i++) { - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - sstr << "#include \"mem/protocol/" << machine->getIdent() << "_Controller.hh\"" << endl; - controller_types.insertAtBottom(machine->getIdent()); - } - } - sstr << endl; - - sstr << "AbstractController* ControllerFactory::createController(const std::string & controller_type, const std::string & name) {" << endl; - for (int i=0;i<controller_types.size();i++) { - sstr << " if (controller_type == \"" << controller_types[i] << "\")" << endl; - sstr << " return new " << controller_types[i] << "_Controller(name);" << endl; - } - sstr << " assert(0); // invalid controller type" << endl; - sstr << " return NULL;" << endl; - sstr << "}" << endl; - conditionally_write_file(path + "/ControllerFactory.cc", sstr); -} - -Vector<StateMachine*> SymbolTable::getStateMachines() const -{ - Vector<StateMachine*> machine_vec; - int size = m_sym_vec.size(); - for(int i=0; i<size; i++) { - StateMachine* type = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (type != NULL) { - machine_vec.insertAtBottom(type); - } - } - return machine_vec; -} - -void SymbolTable::writeHTMLFiles(string path) const -{ - // Create index.html - { - ostringstream out; - createHTMLindex(path, out); - conditionally_write_file(path + "index.html", out); - } - - // Create empty.html - { - ostringstream out; - out << "<HTML></HTML>"; - conditionally_write_file(path + "empty.html", out); - } - - // Write all the symbols - int size = m_sym_vec.size(); - for(int i=0; i<size; i++) { - m_sym_vec[i]->writeHTMLFiles(path); - } -} - -void write_file(string filename, ostringstream& sstr) -{ - ofstream out; - - out.open(filename.c_str()); - out << sstr.str(); - out.close(); -} - -void SymbolTable::writeMIFFiles(string path) const -{ - int size = m_sym_vec.size(); - for(int i=0; i<size; i++) { - ostringstream states, events, actions, transitions; - StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]); - if (machine != NULL) { - printStateTableMIF(*machine, states); - write_file(path + machine->getIdent() + "_states.mif", states); - printEventTableMIF(*machine, events); - write_file(path + machine->getIdent() + "_events.mif", events); - printActionTableMIF(*machine, actions); - write_file(path + machine->getIdent() + "_actions.mif", actions); - printTransitionTableMIF(*machine, transitions); - write_file(path + machine->getIdent() + "_transitions.mif", transitions); - } - } -} - - -void SymbolTable::print(ostream& out) const -{ - out << "[SymbolTable]"; // FIXME -} diff --git a/src/mem/slicc/symbols/SymbolTable.hh b/src/mem/slicc/symbols/SymbolTable.hh deleted file mode 100644 index 90d3f48c3..000000000 --- a/src/mem/slicc/symbols/SymbolTable.hh +++ /dev/null @@ -1,121 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * SymbolTable.hh - * - * Description: - * - * $Id$ - * - * */ - -#ifndef SYMBOLTABLE_H -#define SYMBOLTABLE_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Map.hh" -#include "mem/gems_common/Vector.hh" - -#include "mem/slicc/symbols/Symbol.hh" -#include "mem/slicc/symbols/Type.hh" -#include "mem/slicc/symbols/Var.hh" -#include "mem/slicc/symbols/Func.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -class SymbolTable; - -extern SymbolTable g_sym_table; - -class SymbolTable { -public: - // Constructors - SymbolTable(); - - // Destructor - ~SymbolTable(); - - // Public Methods - void newSym(Symbol* sym_ptr); - void registerSym(string id, Symbol* sym_ptr); - Symbol* getSym(string id) const; - - // used to cheat-- that is, access components in other machines - void newMachComponentSym(Symbol* sym_ptr); - Var* getMachComponentVar(string mach, string ident); - - void newCurrentMachine(StateMachine* machine_ptr); - StateMachine* getStateMachine(string ident) const; - StateMachine* getStateMachine() const { return getStateMachine("current_machine"); } - Type* getType(string ident) const; - - Var* getVar(string ident) const; - Func* getFunc(string ident) const; - - void pushFrame(); - void popFrame(); - - Vector<StateMachine*> getStateMachines() const; - - void writeCFiles(string path) const; - void writeHTMLFiles(string path) const; - void writeMIFFiles(string path) const; - - void print(ostream& out) const; -private: - // Private Methods - void registerGlobalSym(string id, Symbol* sym_ptr); - void writeControllerFactory(string path) const; - - // Private copy constructor and assignment operator - SymbolTable(const SymbolTable& obj); - SymbolTable& operator=(const SymbolTable& obj); - - // Data Members (m_ prefix) - Vector<Symbol*> m_sym_vec; - Vector<Map<string, Symbol*> > m_sym_map_vec; - Map<string, Map<string, Symbol*> > m_machine_component_map_vec; - int m_depth; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const SymbolTable& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const SymbolTable& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //SYMBOLTABLE_H diff --git a/src/mem/slicc/symbols/SymbolTable.py b/src/mem/slicc/symbols/SymbolTable.py new file mode 100644 index 000000000..6b1bf13e6 --- /dev/null +++ b/src/mem/slicc/symbols/SymbolTable.py @@ -0,0 +1,221 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.generate import html +from slicc.symbols.StateMachine import StateMachine +from slicc.symbols.Type import Type +from slicc.util import Location + +class SymbolTable(object): + def __init__(self): + self.sym_vec = [] + self.sym_map_vec = [ {} ] + self.machine_components = {} + + pairs = {} + pairs["enumeration"] = "yes" + MachineType = Type(self, "MachineType", Location("init", 0), pairs) + self.newSymbol(MachineType) + + pairs = {} + pairs["primitive"] = "yes" + pairs["external"] = "yes" + void = Type(self, "void", Location("init", 0), pairs) + self.newSymbol(void) + + def __repr__(self): + return "[SymbolTable]" # FIXME + + def newSymbol(self, sym): + self.registerSym(str(sym), sym) + self.sym_vec.append(sym) + + def registerSym(self, id, sym): + # Check for redeclaration (in the current frame only) + if id in self.sym_map_vec[-1]: + sym.error("Symbol '%s' redeclared in same scope.", id) + + # FIXME - warn on masking of a declaration in a previous frame + self.sym_map_vec[-1][id] = sym + + def find(self, ident, types=None): + for sym_map in reversed(self.sym_map_vec): + try: + symbol = sym_map[ident] + except KeyError: + continue + + if types is not None: + if not isinstance(symbol, types): + symbol.error("Symbol '%s' is not of types '%s'.", + symbol, + types) + + return symbol + + return None + + def newMachComponentSym(self, symbol): + # used to cheat-- that is, access components in other machines + machine = self.find("current_machine", StateMachine) + if machine: + self.machine_components[str(machine)][str(symbol)] = symbol + + def newCurrentMachine(self, sym): + self.registerGlobalSym(str(sym), sym) + self.registerSym("current_machine", sym) + self.sym_vec.append(sym) + + self.machine_components[str(sym)] = {} + + @property + def state_machine(self): + return self.find("current_machine", StateMachine) + + def pushFrame(self): + self.sym_map_vec.append({}) + + def popFrame(self): + assert len(self.sym_map_vec) > 0 + self.sym_map_vec.pop() + + def registerGlobalSym(self, ident, symbol): + # Check for redeclaration (global frame only) + if ident in self.sym_map_vec[0]: + symbol.error("Symbol '%s' redeclared in global scope." % ident) + + self.sym_map_vec[0][ident] = symbol + + def getAllType(self, type): + for symbol in self.sym_vec: + if isinstance(symbol, type): + yield symbol + + def writeCodeFiles(self, path): + code = code_formatter() + code(''' +/** Auto generated C++ code started by $__file__:$__line__ */ + +#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" +''') + for symbol in self.sym_vec: + if isinstance(symbol, Type) and not symbol.isPrimitive: + code('#include "mem/protocol/${{symbol.c_ident}}.hh"') + + code.write(path, "Types.hh") + + for symbol in self.sym_vec: + symbol.writeCodeFiles(path) + + self.writeControllerFactory(path) + + def writeControllerFactory(self, path): + code = code_formatter() + + code(''' +/** \\file ControllerFactory.hh + * Auto generatred C++ code started by $__file__:$__line__ + */ + +#ifndef CONTROLLERFACTORY_H +#define CONTROLLERFACTORY_H + +#include <string> +class Network; +class AbstractController; + +class ControllerFactory { + public: + static AbstractController *createController(const std::string &controller_type, const std::string &name); +}; +#endif // CONTROLLERFACTORY_H''') + code.write(path, "ControllerFactory.hh") + + code = code_formatter() + code(''' +/** \\file ControllerFactory.cc + * Auto generatred C++ code started by $__file__:$__line__ + */ + +#include "mem/protocol/ControllerFactory.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/protocol/MachineType.hh" +''') + + controller_types = [] + for symbol in self.getAllType(StateMachine): + code('#include "mem/protocol/${{symbol.ident}}_Controller.hh"') + controller_types.append(symbol.ident) + + code(''' +AbstractController *ControllerFactory::createController(const std::string &controller_type, const std::string &name) { +''') + + for ct in controller_types: + code(''' + if (controller_type == "$ct") + return new ${ct}_Controller(name); +''') + + code(''' + assert(0); // invalid controller type + return NULL; +} +''') + code.write(path, "ControllerFactory.cc") + + def writeHTMLFiles(self, path): + machines = list(self.getAllType(StateMachine)) + if len(machines) > 1: + name = "%s_table.html" % machines[0].ident + else: + name = "empty.html" + + code = code_formatter() + code(''' +<html> +<head> +<title>$path</title> +</head> +<frameset rows="*,30"> + <frame name="Table" src="$name"> + <frame name="Status" src="empty.html"> +</frameset> +</html> +''') + code.write(path, "index.html") + + code = code_formatter() + code("<HTML></HTML>") + code.write(path, "empty.html") + + for symbol in self.sym_vec: + symbol.writeHTMLFiles(path) + +__all__ = [ "SymbolTable" ] diff --git a/src/mem/slicc/symbols/Transition.cc b/src/mem/slicc/symbols/Transition.cc deleted file mode 100644 index d6d348166..000000000 --- a/src/mem/slicc/symbols/Transition.cc +++ /dev/null @@ -1,173 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#include "mem/slicc/symbols/Transition.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Event.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/gems_common/util.hh" -#include "mem/slicc/symbols/Var.hh" - -Transition::Transition(string state, string event, string nextState, - const Vector<string>& actionList, - const Location& location, - const Map<string, string>& pairMap) - : Symbol(state + "|" + event, location, pairMap) -{ - m_state = state; - m_event = event; - m_nextState = nextState; - m_actionList = actionList; - - // Ptrs are undefined at this point - m_statePtr = NULL; - m_eventPtr = NULL; - m_nextStatePtr = NULL; - m_actionPtrsValid = false; -} - -void Transition::checkIdents(const Vector<State*>& states, - const Vector<Event*>& events, - const Vector<Action*>& actions) -{ - m_statePtr = findIndex(states, m_state); - m_eventPtr = findIndex(events, m_event); - m_nextStatePtr = findIndex(states, m_nextState); - - for(int i=0; i < m_actionList.size(); i++) { - Action* action_ptr = findIndex(actions, m_actionList[i]); - int size = action_ptr->getResources().keys().size(); - for (int j=0; j < size; j++) { - Var* var_ptr = action_ptr->getResources().keys()[j]; - if (var_ptr->getType()->cIdent() != "DNUCAStopTable") { - int num = atoi((action_ptr->getResources().lookup(var_ptr)).c_str()); - if (m_resources.exist(var_ptr)) { - num += atoi((m_resources.lookup(var_ptr)).c_str()); - } - m_resources.add(var_ptr, int_to_string(num)); - } else { - m_resources.add(var_ptr, action_ptr->getResources().lookup(var_ptr)); - } - } - m_actionPtrs.insertAtBottom(action_ptr); - } - m_actionPtrsValid = true; -} - -const string& Transition::getStateShorthand() const -{ - assert(m_statePtr != NULL); - return m_statePtr->getShorthand(); -} - -const string& Transition::getEventShorthand() const -{ - assert(m_eventPtr != NULL); - return m_eventPtr->getShorthand(); -} - -const string& Transition::getNextStateShorthand() const -{ - assert(m_nextStatePtr != NULL); - return m_nextStatePtr->getShorthand(); -} - -string Transition::getActionShorthands() const -{ - assert(m_actionPtrsValid); - string str; - int numActions = m_actionPtrs.size(); - for (int i=0; i<numActions; i++) { - str += m_actionPtrs[i]->getShorthand(); - } - return str; -} - -void Transition::print(ostream& out) const -{ - out << "[Transition: "; - out << "(" << m_state; - if (m_statePtr != NULL) { - out << ":" << *m_statePtr; - } - out << ", " << m_event; - if (m_eventPtr != NULL) { - out << ":" << *m_eventPtr; - } - out << ") -> "; - out << m_nextState; - if (m_nextStatePtr != NULL) { - out << ":" << *m_nextStatePtr; - } - out << ", "; - out << m_actionList; - out << "]"; -} - -Event* Transition::findIndex(const Vector<Event*>& vec, string ident) -{ - int size = vec.size(); - for(int i=0; i<size; i++) { - if (ident == vec[i]->getIdent()) { - return vec[i]; - } - } - error("Event not found: " + ident); - return NULL; -} - -State* Transition::findIndex(const Vector<State*>& vec, string ident) -{ - int size = vec.size(); - for(int i=0; i<size; i++) { - if (ident == vec[i]->getIdent()) { - return vec[i]; - } - } - error("State not found: " + ident); - return NULL; -} - -Action* Transition::findIndex(const Vector<Action*>& vec, string ident) -{ - int size = vec.size(); - for(int i=0; i<size; i++) { - if (ident == vec[i]->getIdent()) { - return vec[i]; - } - } - error("Action not found: " + ident); - return NULL; -} - diff --git a/src/mem/slicc/symbols/Transition.hh b/src/mem/slicc/symbols/Transition.hh deleted file mode 100644 index 75d6da4e9..000000000 --- a/src/mem/slicc/symbols/Transition.hh +++ /dev/null @@ -1,120 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Transition.hh - * - * Description: - * - * $Id$ - * - * */ - -#ifndef TRANSITION_H -#define TRANSITION_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Vector.hh" -#include "mem/slicc/symbols/Symbol.hh" - -class State; -class Event; -class Action; -class Var; - -class Transition : public Symbol { -public: - // Constructors - Transition(string state, string event, string nextState, - const Vector<string>& actionList, - const Location& location, - const Map<string, string>& pairMap); - // Destructor - ~Transition() { } - - // Public Methods - State* getStatePtr() const { assert(m_statePtr != NULL); return m_statePtr; } - Event* getEventPtr() const { assert(m_eventPtr != NULL); return m_eventPtr; } - State* getNextStatePtr() const { assert(m_nextStatePtr != NULL); return m_nextStatePtr; } - - // int getStateIndex() const { assert(m_statePtr != NULL); return m_statePtr->getIndex(); } - // int getEventIndex() const { assert(m_eventPtr != NULL); return m_eventPtr->getIndex(); } - // int getNextStateIndex() const { assert(m_nextStatePtr != NULL); return m_nextStatePtr->getIndex(); } - void checkIdents(const Vector<State*>& states, - const Vector<Event*>& events, - const Vector<Action*>& actions); - - const string& getStateShorthand() const; - const string& getEventShorthand() const; - const string& getNextStateShorthand() const; - string getActionShorthands() const; - const Vector<Action*>& getActions() const { assert(m_actionPtrsValid); return m_actionPtrs; } - const Map<Var*, string>& getResources() const { assert(m_actionPtrsValid); return m_resources; } - - void print(ostream& out) const; - - // Default copy constructor and assignment operator - // Transition(const Transition& obj); - // Transition& operator=(const Transition& obj); -private: - // Private Methods - Event* findIndex(const Vector<Event*>& vec, string ident); - State* findIndex(const Vector<State*>& vec, string ident); - Action* findIndex(const Vector<Action*>& vec, string ident); - - // Data Members (m_ prefix) - string m_state; - string m_event; - string m_nextState; - - State* m_statePtr; - Event* m_eventPtr; - State* m_nextStatePtr; - - Vector<string> m_actionList; - Vector<Action*> m_actionPtrs; - Map<Var*, string> m_resources; - bool m_actionPtrsValid; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Transition& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Transition& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TRANSITION_H diff --git a/src/mem/slicc/symbols/Transition.py b/src/mem/slicc/symbols/Transition.py new file mode 100644 index 000000000..1bf09048a --- /dev/null +++ b/src/mem/slicc/symbols/Transition.py @@ -0,0 +1,61 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class Transition(Symbol): + def __init__(self, table, machine, state, event, nextState, actions, + location, pairs): + ident = "%s|%s" % (state, event) + super(Transition, self).__init__(table, ident, location, pairs) + + self.state = machine.states[state] + self.event = machine.events[event] + self.nextState = machine.states[nextState] + self.actions = [ machine.actions[a] for a in actions ] + self.resources = {} + + for action in self.actions: + for var,value in action.resources.iteritems(): + if var.type.ident != "DNUCAStopTable": + num = int(value) + if var in self.resources: + num += int(value) + self.resources[var] = str(num) + else: + self.resources[var] = value + + def __repr__(self): + return "[Transition: (%r, %r) -> %r, %r]" % \ + (self.state, self.event, self.nextState, self.actions) + + def getActionShorthands(self): + assert self.actions + + return ''.join(a.short for a in self.actions) + +__all__ = [ "Transition" ] diff --git a/src/mem/slicc/symbols/Type.cc b/src/mem/slicc/symbols/Type.cc deleted file mode 100644 index 5afe53423..000000000 --- a/src/mem/slicc/symbols/Type.cc +++ /dev/null @@ -1,779 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Type.cc - * - * Description: See Type.hh - * - * $Id$ - * */ - -#include "mem/slicc/symbols/Type.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/gems_common/Map.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -Type::Type(string id, const Location& location, - const Map<string, string>& pairs, - StateMachine* machine_ptr) - : Symbol(id, location, pairs) -{ - if (machine_ptr == NULL) { - m_c_id = id; - } else if (isExternal() || isPrimitive()) { - if (existPair("external_name")) { - m_c_id = lookupPair("external_name"); - } else { - m_c_id = id; - } - } else { - m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name - } - - if(existPair("desc")){ - m_desc = lookupPair("desc"); - } else { - m_desc = "No description avaliable"; - } - - // check for interface that this Type implements - if(existPair("interface")) { - string interface = lookupPair("interface"); - if(interface == "Message" || interface == "NetworkMessage") { - addPair("message", "yes"); - } - if(interface == "NetworkMessage") { - addPair("networkmessage", "yes"); - } - } - - // FIXME - all of the following id comparisons are fragile hacks - if ((getIdent() == "CacheMemory") || (getIdent() == "NewCacheMemory") || - (getIdent() == "TLCCacheMemory") || (getIdent() == "DNUCACacheMemory") || - (getIdent() == "DNUCABankCacheMemory") || (getIdent() == "L2BankCacheMemory") || - (getIdent() == "CompressedCacheMemory") || (getIdent() == "PrefetchCacheMemory")) { - addPair("cache", "yes"); - } - - if ((getIdent() == "TBETable") || (getIdent() == "DNUCATBETable") || (getIdent() == "DNUCAStopTable")) { - addPair("tbe", "yes"); - } - - if ((getIdent() == "NewTBETable")) { - addPair("newtbe", "yes"); - } - - if ((getIdent() == "TimerTable")) { - addPair("timer", "yes"); - } - - if ((getIdent() == "DirectoryMemory")) { - addPair("dir", "yes"); - } - - if ((getIdent() == "PersistentTable")) { - addPair("persistent", "yes"); - } - - if ((getIdent() == "Prefetcher")) { - addPair("prefetcher", "yes"); - } - - if ((getIdent() == "DNUCA_Movement")) { - addPair("mover", "yes"); - } - - if (id == "MachineType") { - m_isMachineType = true; - } else { - m_isMachineType = false; - } -} - -// Return false on error -bool Type::dataMemberAdd(string id, Type* type_ptr, Map<string, string>& pairs, - string* init_code) -{ - if (dataMemberExist(id)) { - return false; // Error - } else { - m_data_member_map.add(id, type_ptr); - m_data_member_ident_vec.insertAtBottom(id); - m_data_member_type_vec.insertAtBottom(type_ptr); - m_data_member_pairs_vec.insertAtBottom(pairs); - m_data_member_init_code_vec.insertAtBottom(init_code); - } - - return true; -} - -string Type::methodId(string name, - const Vector<Type*>& param_type_vec) -{ - string paramStr = ""; - for (int i = 0; i < param_type_vec.size(); i++) { - paramStr += "_"+param_type_vec[i]->cIdent(); - } - return name+paramStr; -} - -bool Type::methodAdd(string name, - Type* return_type_ptr, - const Vector<Type*>& param_type_vec) -{ - string id = methodId(name, param_type_vec); - if (methodExist(id)) { - return false; // Error - } else { - m_method_return_type_map.add(id, return_type_ptr); - m_method_param_type_map.add(id, param_type_vec); - return true; - } -} - -bool Type::enumAdd(string id, Map<string, string> pairs_map) -{ - if (enumExist(id)) { - return false; - } else { - m_enum_map.add(id, true); - m_enum_vec.insertAtBottom(id); - m_enum_pairs.insertAtBottom(pairs_map); - - // Add default - if (!existPair("default")) { - addPair("default", cIdent()+"_NUM"); - } - - return true; - } -} - -void Type::writeCFiles(string path) -{ - if (isExternal()) { - // Do nothing - } else if (isEnumeration()) { - printEnumH(path); - printEnumC(path); - } else { // User defined structs and messages - printTypeH(path); - printTypeC(path); - } -} - -void Type::printTypeH(string path) const -{ - ostringstream out; - int size = m_data_member_type_vec.size(); - string type_name = cIdent(); // Identifier for the type in C - - // Header - out << "/** \\file " << type_name << ".hh" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " */" << endl; - out << endl; - out << "#ifndef " << type_name << "_H" << endl; - out << "#define " << type_name << "_H" << endl; - out << endl; - - // Include all of the #includes needed - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/gems_common/Allocator.hh\"" << endl; - for (int i=0; i < size; i++) { - Type* type = m_data_member_type_vec[i]; - if (!type->isPrimitive()) { - out << "#include \"mem/protocol/" << type->cIdent() << ".hh" << "\"" << endl; - } - } - string interface = ""; - if(existPair("interface")) { - interface = lookupPair("interface"); - out << "#include \"mem/protocol/" << interface << ".hh\"" << endl; - } - - // Class definition - out << "class " << type_name; - - if(interface != "") { - out << " : public " << interface ; - } - - out << " {" << endl; - out << "public:" << endl; - - // ******** Default constructor ******** - - out << " " << type_name << "() " << endl; - - // Call superclass constructor - if (interface != "") { - out << " : " << interface << "()" << endl; - } - - out << " {" << endl; - - if(!isGlobal()) { - for (int i=0; i < size; i++) { - - Type* type_ptr = m_data_member_type_vec[i]; - string id = m_data_member_ident_vec[i]; - if (m_data_member_pairs_vec[i].exist("default")) { - // look for default value - string default_value = m_data_member_pairs_vec[i].lookup("default"); - out << " m_" << id << " = " << default_value << "; // default for this field " << endl; - } else if (type_ptr->hasDefault()) { - // Look for the type default - string default_value = type_ptr->getDefault(); - out << " m_" << id << " = " << default_value << "; // default value of " << type_ptr->cIdent() << endl; - } else { - out << " // m_" << id << " has no default" << endl; - } - } - } // end of if(!isGlobal()) - out << " }" << endl; - - // ******** Default destructor ******** - out << " "; - out << "~" << type_name << "() { };" << endl; - - // ******** Full init constructor ******** - if(! isGlobal()) { - out << " " << type_name << "("; - - for (int i=0; i < size; i++) { - if (i != 0) { - out << ", "; - } - Type* type = m_data_member_type_vec[i]; - string id = m_data_member_ident_vec[i]; - out << "const " << type->cIdent() << "& local_" << id; - } - - if (isMessage()) { - out << ", const unsigned local_proc_id" << flush; - } - - out << ")" << endl; - - // Call superclass constructor - if (interface != "") { - out << " : " << interface << "()" << endl; - } - - out << " {" << endl; - for (int i=0; i < size; i++) { - Type* type_ptr = m_data_member_type_vec[i]; - string id = m_data_member_ident_vec[i]; - out << " m_" << id << " = local_" << id << ";" << endl; - if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) { - string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack"); - out << " m_" << id << next_line_value << ";" << endl; - } - } - if (isMessage()) { - out << " proc_id = local_proc_id;" << endl << flush; - } - out << " }" << endl; - } // end of if(!isGlobal()) - - // create a static factory method - if (interface != "") { - out << " static " << interface << "* create() {" << endl; - out << " return new " << type_name << "(); " << endl; - out << " }" << endl; - } - - // bobba - - //******** Partial init constructor ******** - //** Constructor needs only the first n-1 data members for init - //** HACK to create objects with partially specified data members - //** Need to get rid of this and use hierarchy instead -// if(! isGlobal()) { -// out << " " << type_name << "("; - -// for (int i=0; i < size-1; i++) { -// if (i != 0) { -// out << ", "; -// } -// Type* type = m_data_member_type_vec[i]; -// string id = m_data_member_ident_vec[i]; -// out << "const " << type->cIdent() << "& local_" << id; -// } -// out << ")" << endl; - -// // Call superclass constructor -// if (interface != "") { -// out << " : " << interface << "()" << endl; -// } - -// out << " {" << endl; -// for (int i=0; i < size-1; i++) { -// Type* type_ptr = m_data_member_type_vec[i]; -// string id = m_data_member_ident_vec[i]; -// out << " m_" << id << " = local_" << id << ";" << endl; -// if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) { -// string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack"); -// out << " m_" << id << next_line_value << ";" << endl; -// } - -// } -// out << " }" << endl; -// } // end of if(!isGlobal()) - - // ******** Message member functions ******** - // FIXME: those should be moved into slicc file, slicc should support more of - // the c++ class inheritance - - if (isMessage()) { - out << " Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); }" << endl; - out << " void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); }" << endl; - out << " static Allocator<" << type_name << ">* s_allocator_ptr;" << endl; - out << " static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<" << type_name << ">; }}" << endl; - } - - if(!isGlobal()) { - // const Get methods for each field - out << " // Const accessors methods for each field" << endl; - for (int i=0; i < size; i++) { - Type* type_ptr = m_data_member_type_vec[i]; - string type = type_ptr->cIdent(); - string id = m_data_member_ident_vec[i]; - out << "/** \\brief Const accessor method for " << id << " field." << endl; - out << " * \\return " << id << " field" << endl; - out << " */" << endl; - out << " const " << type << "& get" << id - << "() const { return m_" << id << "; }" << endl; - } - - out << endl; - - // Non-const Get methods for each field - out << " // Non const Accessors methods for each field" << endl; - for (int i=0; i < size; i++) { - Type* type_ptr = m_data_member_type_vec[i]; - string type = type_ptr->cIdent(); - string id = m_data_member_ident_vec[i]; - out << "/** \\brief Non-const accessor method for " << id << " field." << endl; - out << " * \\return " << id << " field" << endl; - out << " */" << endl; - out << " " << type << "& get" << id - << "() { return m_" << id << "; }" << endl; - } - - out << endl; - - // Set methods for each field - out << " // Mutator methods for each field" << endl; - for (int i=0; i < size; i++) { - Type* type_ptr = m_data_member_type_vec[i]; - string type = type_ptr->cIdent(); - string id = m_data_member_ident_vec[i]; - out << "/** \\brief Mutator method for " << id << " field */" << endl; - out << " void set" << id << "(const " << type << "& local_" - << id << ") { m_" << id << " = local_" << id << "; }" << endl; - } - - out << endl; - } // end of if(!isGlobal()) - - out << " void print(ostream& out) const;" << endl; - out << "//private:" << endl; - - // Data members for each field - for (int i=0; i < size; i++) { - if (!m_data_member_pairs_vec[i].exist("abstract")) { - out << " "; - // global structure - if(isGlobal()) out << "static const "; - - Type* type = m_data_member_type_vec[i]; - string id = m_data_member_ident_vec[i]; - out << type->cIdent() << " m_" << id; - - // init value - string* init_code = m_data_member_init_code_vec[i]; - if(init_code) { - // only global structure can have init value here - assert(isGlobal()); - out << " = " << *init_code << " "; - } - out << ";"; - if (m_data_member_pairs_vec[i].exist("desc")) { - string desc = m_data_member_pairs_vec[i].lookup("desc"); - out << " /**< " << desc << "*/"; - } - out << endl; - } - } - - if (isMessage()) { - out << " unsigned proc_id;" << endl << flush; - } - - out << "};" << endl; // End class - - out << "// Output operator declaration" << endl; - out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl; - out << endl; - out << "// Output operator definition" << endl; - out << "extern inline" << endl; - out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl; - out << "{" << endl; - out << " obj.print(out);" << endl; - out << " out << flush;" << endl; - out << " return out;" << endl; - out << "}" << endl; - out << endl; - out << "#endif // " << type_name << "_H" << endl; - - // Write it out - conditionally_write_file(path + type_name + ".hh", out); -} - -void Type::printTypeC(string path) const -{ - ostringstream out; - int size = m_data_member_type_vec.size(); - string type_name = cIdent(); // Identifier for the type in C - - // Header - out << "/** \\file " << type_name << ".cc" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " */" << endl; - out << endl; - out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl; - out << endl; - if (isMessage()) { - out << "Allocator<" << type_name << ">* " << type_name << "::s_allocator_ptr = NULL;" << endl; - } - out << "/** \\brief Print the state of this object */" << endl; - out << "void " << type_name << "::print(ostream& out) const" << endl; - out << "{" << endl; - out << " out << \"[" << type_name << ": \";" << endl; - - // For each field - for (int i=0; i < size; i++) { - string id = m_data_member_ident_vec[i]; - out << " out << \"" << id << "=\" << m_" << id << " << \" \";" << endl; - } - - if (isMessage()) { - out << " out << \"" << "Time" << "=\" << getTime()" << " << \" \";" << endl; - } - - // Trailer - out << " out << \"]\";" << endl; - out << "}" << endl; - - // Write it out - conditionally_write_file(path + type_name + ".cc", out); -} - -void Type::printEnumH(string path) const -{ - ostringstream out; - int size = m_enum_vec.size(); - string type_name = cIdent(); // Identifier for the type in C - string type_desc = desc(); - - // Header - out << "/** \\file " << type_name << ".hh" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " */" << endl; - - out << "#ifndef " << type_name << "_H" << endl; - out << "#define " << type_name << "_H" << endl; - out << endl; - // Include all of the #includes needed - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << endl; - - // Class definition - out << "/** \\enum " << type_name << endl; - out << " * \\brief " << type_desc << endl; - out << " */" << endl; - out << "enum " << type_name << " {" << endl; - - out << " " << type_name << "_FIRST," << endl; - - // For each field - for(int i = 0; i < size; i++ ) { - string id = m_enum_vec[i]; - string description; - if(m_enum_pairs[i].exist("desc")){ - description = m_enum_pairs[i].lookup("desc"); - } else { - description = "No description avaliable"; - } - if (i == 0) { - out << " " << type_name << "_" << id << " = " << type_name << "_FIRST, /**< " << description << " */" << endl; - } - else { - out << " " << type_name << "_" << id << ", /**< " << description << " */" << endl; - } - } - out << " " << type_name << "_NUM" << endl; - out << "};" << endl; - - // Code to convert from a string to the enumeration - out << type_name << " string_to_" << type_name << "(const string& str);" << endl; - - // Code to convert state to a string - out << "string " << type_name << "_to_string(const " << type_name << "& obj);" << endl; - - // Code to increment an enumeration type - out << type_name << " &operator++( " << type_name << " &e);" << endl; - - // MachineType hack used to set the base component id for each Machine - if (m_isMachineType) { - out << "int " << type_name << "_base_level(const " << type_name << "& obj);" << endl; - out << "MachineType " << type_name << "_from_base_level(int);" << endl; - out << "int " << type_name << "_base_number(const " << type_name << "& obj);" << endl; - out << "int " << type_name << "_base_count(const " << type_name << "& obj);" << endl; - // out << "int " << type_name << "_chip_count(const " << type_name << "& obj, int chipID);" << endl; - - for(int i = 0; i < size; i++ ) { - string id = m_enum_vec[i]; - out << "#define MACHINETYPE_" << id << " 1" << endl; - } - cout << endl; - } - - // Trailer - out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl; - out << endl; - out << "#endif // " << type_name << "_H" << endl; - - // Write the file - conditionally_write_file(path + type_name + ".hh", out); -} - -void Type::printEnumC(string path) const -{ - ostringstream out; - int size = m_enum_vec.size(); - string type_name = cIdent(); // Identifier for the type in C - - // Header - out << "/** \\file " << type_name << ".hh" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " */" << endl; - - out << endl; - out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl; - if (m_isMachineType) { - out << "#include \"mem/protocol/ControllerFactory.hh\"" << endl; - for( int i = 0; i<size; i++ ) { - out << "#include \"mem/protocol/" << m_enum_vec[i] << "_Controller.hh\"" << endl; - } - out << endl; - } - out << endl; - - // Code for output operator - out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl; - out << "{" << endl; - out << " out << " << type_name << "_to_string(obj);" << endl; - out << " out << flush;" << endl; - out << " return out;" << endl; - out << "}" << endl; - - // Code to convert state to a string - out << endl; - out << "string " << type_name << "_to_string(const " << type_name << "& obj)" << endl; - out << "{" << endl; - out << " switch(obj) {" << endl; - - // For each field - for( int i = 0; i<size; i++ ) { - out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl; - out << " return \"" << m_enum_vec[i] << "\";" << endl; - } - - // Trailer - out << " default:" << endl; - out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl; - out << " return \"\";" << endl; - out << " }" << endl; - out << "}" << endl; - - // Code to convert from a string to the enumeration - out << endl; - out << type_name << " string_to_" << type_name << "(const string& str)" << endl; - out << "{" << endl; - out << " if (false) {" << endl; - - // For each field - for( int i = 0; i<size; i++ ) { - out << " } else if (str == \"" << m_enum_vec[i] << "\") {" << endl; - out << " return " << type_name << "_" << m_enum_vec[i] << ";" << endl; - } - - out << " } else {" << endl; - out << " WARN_EXPR(str);" << endl; - out << " ERROR_MSG(\"Invalid string conversion for type " << type_name << "\");" << endl; - out << " }" << endl; - out << "}" << endl; - - // Code to increment an enumeration type - out << endl; - out << type_name << "& operator++( " << type_name << "& e) {" << endl; - out << " assert(e < " << type_name << "_NUM);" << endl; - out << " return e = " << type_name << "(e+1);" << endl; - out << "}" << endl; - - // MachineType hack used to set the base level and number of components for each Machine - if (m_isMachineType) { - out << endl; - out << "/** \\brief returns the base vector index for each machine type to be used by NetDest " << endl; - out << " * " << endl; - out << " * \\return the base vector index for each machine type to be used by NetDest" << endl; - out << " * \\see NetDest.hh" << endl; - out << " */" << endl; - out << "int " << type_name << "_base_level(const " << type_name << "& obj)" << endl; - out << "{" << endl; - out << " switch(obj) {" << endl; - - // For each field - Vector < string > MachineNames; - for( int i = 0; i<size; i++ ) { - out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl; - out << " return " << MachineNames.size() << ";" << endl; - MachineNames.insertAtBottom(m_enum_vec[i]); - } - - // total num - out << " case " << type_name << "_NUM:" << endl; - out << " return " << MachineNames.size() << ";" << endl; - - // Trailer - out << " default:" << endl; - out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl; - out << " return -1;" << endl; - out << " }" << endl; - out << "}" << endl; - - out << "/** \\brief returns the machine type for each base vector index used by NetDest" << endl; - out << " * " << endl; - out << " * \\return the MachineTYpe" << endl; - out << " */" << endl; - out << "MachineType " << type_name << "_from_base_level(int type)" << endl; - out << "{" << endl; - out << " switch(type) {" << endl; - - // For each field - MachineNames.clear(); - for( int i = 0; i<size; i++ ) { - out << " case " << MachineNames.size() << ":" << endl; - out << " return " << type_name << "_" << m_enum_vec[i] << ";" << endl; - MachineNames.insertAtBottom(m_enum_vec[i]); - } - - // Trailer - out << " default:" << endl; - out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl; - out << " return MachineType_NUM;" << endl; - out << " }" << endl; - out << "}" << endl; - - - out << endl; - out << "/** \\brief The return value indicates the number of components created" << endl; - out << " * before a particular machine's components" << endl; - out << " * " << endl; - out << " * \\return the base number of components for each machine" << endl; - out << " */" << endl; - out << "int " << type_name << "_base_number(const " << type_name << "& obj)" << endl; - out << "{" << endl; - out << " switch(obj) {" << endl; - - // For each field - MachineNames.clear(); - for( int i = 0; i<size; i++ ) { - out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl; - out << " return 0"; - for ( int m = 0; m<MachineNames.size(); m++) { - out << "+ " << MachineNames[m] << "_Controller::getNumControllers()"; - } - out << ";" << endl; - MachineNames.insertAtBottom(m_enum_vec[i]); - } - - // total num - out << " case " << type_name << "_NUM:" << endl; - out << " return 0"; - for ( int m = 0; m<MachineNames.size(); m++) { - out << "+ " << MachineNames[m] << "_Controller::getNumControllers()"; - } - out << ";" << endl; - - // Trailer - out << " default:" << endl; - out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl; - out << " return -1;" << endl; - out << " }" << endl; - out << "}" << endl; - - - out << endl; - out << "/** \\brief returns the total number of components for each machine" << endl; - out << " * \\return the total number of components for each machine" << endl; - out << " */" << endl; - out << "int " << type_name << "_base_count(const " << type_name << "& obj)" << endl; - out << "{" << endl; - out << " switch(obj) {" << endl; - - // For each field - for( int i = 0; i<size; i++ ) { - out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl; - out << " return " << m_enum_vec[i] << "_Controller::getNumControllers();" << endl; - } - - // total num - out << " case " << type_name << "_NUM:" << endl; - // Trailer - out << " default:" << endl; - out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl; - out << " return -1;" << endl; - out << " }" << endl; - out << "}" << endl; - - out << endl; - - } - - // Write the file - conditionally_write_file(path + type_name + ".cc", out); -} diff --git a/src/mem/slicc/symbols/Type.hh b/src/mem/slicc/symbols/Type.hh deleted file mode 100644 index 07d661d3c..000000000 --- a/src/mem/slicc/symbols/Type.hh +++ /dev/null @@ -1,155 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Type.hh - * - * Description: - * - * $Id$ - * - * */ - -#ifndef TYPE_H -#define TYPE_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Map.hh" -#include "mem/slicc/symbols/Symbol.hh" - -class StateMachine; - -class Type : public Symbol { -public: - // Constructors - Type(string id, const Location& location, - const Map<string, string>& pairs, - StateMachine* machine_ptr = NULL); - - // Destructor - ~Type() {} - - // Public Methods - string cIdent() const { return m_c_id; } - string desc() const { return m_desc; } - - bool isPrimitive() const { return existPair("primitive"); } - bool isNetworkMessage() const { return existPair("networkmessage"); } - bool isMessage() const { return existPair("message"); } - bool isBuffer() const { return existPair("buffer"); } - bool isInPort() const { return existPair("inport"); } - bool isOutPort() const { return existPair("outport"); } - bool isEnumeration() const { return existPair("enumeration"); } - bool isExternal() const { return existPair("external"); } - bool isGlobal() const { return existPair("global"); } - bool isInterface() const { return existPair("interface"); } - - // The data members of this type - only valid for messages and SLICC - // declared structures - // Return false on error - bool dataMemberAdd(string id, Type* type_ptr, Map<string, string>& pairs, - string* init_code); - bool dataMemberExist(string id) const { return m_data_member_map.exist(id); } - Type* dataMemberType(string id) const { return m_data_member_map.lookup(id); } - - // The methods of this type - only valid for external types - // Return false on error - bool methodAdd(string name, Type* return_type_ptr, const Vector<Type*>& param_type_vec); - bool methodExist(string id) const { return m_method_return_type_map.exist(id); } - - string methodId(string name, const Vector<Type*>& param_type_vec); - Type* methodReturnType(string id) const { return m_method_return_type_map.lookup(id); } - const Vector<Type*>& methodParamType(string id) const { return m_method_param_type_map.lookup(id); } - - // The enumeration idents of this type - only valid for enums - // Return false on error - bool enumAdd(string id, Map<string, string> pairs); - bool enumExist(string id) const { return m_enum_map.exist(id); } - - // Write the C output files - void writeCFiles(string path) ; - - bool hasDefault() const { return existPair("default"); } - string getDefault() const { return lookupPair("default"); } - - void print(ostream& out) const {} -private: - // Private Methods - - void printTypeH(string path) const; - void printTypeC(string path) const; - void printEnumC(string path) const; - void printEnumH(string path) const; - - // Private copy constructor and assignment operator - Type(const Type& obj); - Type& operator=(const Type& obj); - - // Data Members (m_ prefix) - string m_c_id; - string m_desc; - - // Data Members - Map<string, Type*> m_data_member_map; - Vector<string> m_data_member_ident_vec; - Vector<Type*> m_data_member_type_vec; - Vector<Map<string, string> > m_data_member_pairs_vec; - Vector<string*> m_data_member_init_code_vec; - // Needs pairs here - - // Methods - Map<string, Type*> m_method_return_type_map; - Map<string, Vector<Type*> > m_method_param_type_map; - // Needs pairs here - - // Enum - Map<string, bool> m_enum_map; - Vector<string> m_enum_vec; - Vector< Map < string, string > > m_enum_pairs; - - // MachineType Hack - bool m_isMachineType; - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Type& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Type& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TYPE_H diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py new file mode 100644 index 000000000..bafc6ea9e --- /dev/null +++ b/src/mem/slicc/symbols/Type.py @@ -0,0 +1,652 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter, orderdict + +from slicc.util import PairContainer +from slicc.symbols.Symbol import Symbol + +class DataMember(PairContainer): + def __init__(self, ident, type, pairs, init_code): + super(DataMember, self).__init__(pairs) + self.ident = ident + self.type = type + self.init_code = init_code + +class Enumeration(PairContainer): + def __init__(self, ident, pairs): + super(Enumeration, self).__init__(pairs) + self.ident = ident + +class Method(object): + def __init__(self, return_type, param_types): + self.return_type = return_type + self.param_types = param_types + +class Type(Symbol): + def __init__(self, table, ident, location, pairs, machine=None): + super(Type, self).__init__(table, ident, location, pairs) + self.c_ident = ident + if machine: + if self.isExternal or self.isPrimitive: + if "external_name" in self: + self.c_ident = self["external_name"] + else: + # Append with machine name + self.c_ident = "%s_%s" % (machine, ident) + + self.pairs.setdefault("desc", "No description avaliable") + + # check for interface that this Type implements + if "interface" in self: + interface = self["interface"] + if interface in ("Message", "NetworkMessage"): + self["message"] = "yes" + if interface == "NetworkMessage": + self["networkmessage"] = "yes" + + # FIXME - all of the following id comparisons are fragile hacks + if self.ident in ("CacheMemory", "NewCacheMemory", + "TLCCacheMemory", "DNUCACacheMemory", + "DNUCABankCacheMemory", "L2BankCacheMemory", + "CompressedCacheMemory", "PrefetchCacheMemory"): + self["cache"] = "yes" + + if self.ident in ("TBETable", "DNUCATBETable", "DNUCAStopTable"): + self["tbe"] = "yes" + + if self.ident == "NewTBETable": + self["newtbe"] = "yes" + + if self.ident == "TimerTable": + self["timer"] = "yes" + + if self.ident == "DirectoryMemory": + self["dir"] = "yes" + + if self.ident == "PersistentTable": + self["persistent"] = "yes" + + if self.ident == "Prefetcher": + self["prefetcher"] = "yes" + + if self.ident == "DNUCA_Movement": + self["mover"] = "yes" + + self.isMachineType = (ident == "MachineType") + + self.data_members = orderdict() + + # Methods + self.methods = {} + + # Enums + self.enums = orderdict() + + @property + def isPrimitive(self): + return "primitive" in self + @property + def isNetworkMessage(self): + return "networkmessage" in self + @property + def isMessage(self): + return "message" in self + @property + def isBuffer(self): + return "buffer" in self + @property + def isInPort(self): + return "inport" in self + @property + def isOutPort(self): + return "outport" in self + @property + def isEnumeration(self): + return "enumeration" in self + @property + def isExternal(self): + return "external" in self + @property + def isGlobal(self): + return "global" in self + @property + def isInterface(self): + return "interface" in self + + # Return false on error + def dataMemberAdd(self, ident, type, pairs, init_code): + if ident in self.data_members: + return False + + member = DataMember(ident, type, pairs, init_code) + self.data_members[ident] = member + + return True + + def dataMemberType(self, ident): + return self.data_members[ident].type + + def methodId(self, name, param_type_vec): + return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ]) + + def methodAdd(self, name, return_type, param_type_vec): + ident = self.methodId(name, param_type_vec) + if ident in self.methods: + return False + + self.methods[ident] = Method(return_type, param_type_vec) + return True + + def enumAdd(self, ident, pairs): + if ident in self.enums: + return False + + self.enums[ident] = Enumeration(ident, pairs) + + # Add default + if "default" not in self: + self["default"] = "%s_NUM" % self.c_ident + + return True + + def writeCodeFiles(self, path): + if self.isExternal: + # Do nothing + pass + elif self.isEnumeration: + self.printEnumHH(path) + self.printEnumCC(path) + else: + # User defined structs and messages + self.printTypeHH(path) + self.printTypeCC(path) + + def printTypeHH(self, path): + code = code_formatter() + code(''' +/** \\file ${{self.c_ident}}.hh + * + * + * Auto generated C++ code started by $__file__:$__line__ + */ + +#ifndef ${{self.c_ident}}_H +#define ${{self.c_ident}}_H + +#include "mem/ruby/common/Global.hh" +#include "mem/gems_common/Allocator.hh" +''') + + for dm in self.data_members.values(): + if not dm.type.isPrimitive: + code('#include "mem/protocol/$0.hh"', dm.type.c_ident) + + parent = "" + if "interface" in self: + code('#include "mem/protocol/$0.hh"', self["interface"]) + parent = " : public %s" % self["interface"] + + code(''' +$klass ${{self.c_ident}}$parent { + public: + ${{self.c_ident}}() +''', klass="class") + + # Call superclass constructor + if "interface" in self: + code(' : ${{self["interface"]}}()') + + code.indent() + code("{") + if not self.isGlobal: + code.indent() + for dm in self.data_members.values(): + ident = dm.ident + if "default" in dm: + # look for default value + code('m_$ident = ${{dm["default"]}}; // default for this field') + elif "default" in dm.type: + # Look for the type default + tid = dm.type.c_ident + code('m_$ident = ${{dm.type["default"]}}; // default value of $tid') + else: + code('// m_$ident has no default') + code.dedent() + code('}') + + # ******** Default destructor ******** + code('~${{self.c_ident}}() { };') + + # ******** Full init constructor ******** + if not self.isGlobal: + params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \ + for dm in self.data_members.itervalues() ] + + if self.isMessage: + params.append('const unsigned local_proc_id') + + params = ', '.join(params) + code('${{self.c_ident}}($params)') + + # Call superclass constructor + if "interface" in self: + code(' : ${{self["interface"]}}()') + + code('{') + code.indent() + for dm in self.data_members.values(): + code('m_${{dm.ident}} = local_${{dm.ident}};') + if "nextLineCallHack" in dm: + code('m_${{dm.ident}}${{dm["nextLineCallHack"]}};') + + if self.isMessage: + code('proc_id = local_proc_id;') + + code.dedent() + code('}') + + # create a static factory method + if "interface" in self: + code(''' +static ${{self["interface"]}}* create() { + return new ${{self.c_ident}}(); +} +''') + + # ******** Message member functions ******** + # FIXME: those should be moved into slicc file, slicc should + # support more of the c++ class inheritance + + if self.isMessage: + code(''' +Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); } +void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); } +static Allocator<${{self.c_ident}}>* s_allocator_ptr; +static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<${{self.c_ident}}>; }} +''') + + if not self.isGlobal: + # const Get methods for each field + code('// Const accessors methods for each field') + for dm in self.data_members.values(): + code(''' +/** \\brief Const accessor method for ${{dm.ident}} field. + * \\return ${{dm.ident}} field + */ +const ${{dm.type.c_ident}}& get${{dm.ident}}() const { return m_${{dm.ident}}; } +''') + + # Non-const Get methods for each field + code('// Non const Accessors methods for each field') + for dm in self.data_members.values(): + code(''' +/** \\brief Non-const accessor method for ${{dm.ident}} field. + * \\return ${{dm.ident}} field + */ +${{dm.type.c_ident}}& get${{dm.ident}}() { return m_${{dm.ident}}; } +''') + + #Set methods for each field + code('// Mutator methods for each field') + for dm in self.data_members.values(): + code(''' +/** \\brief Mutator method for ${{dm.ident}} field */ +void set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) { m_${{dm.ident}} = local_${{dm.ident}}; } +''') + + code('void print(ostream& out) const;') + code.dedent() + code(' //private:') + code.indent() + + # Data members for each field + for dm in self.data_members.values(): + if "abstract" not in dm: + const = "" + init = "" + + # global structure + if self.isGlobal: + const = "static const " + + # init value + if dm.init_code: + # only global structure can have init value here + assert self.isGlobal + init = " = %s" % (dm.init_code) + + desc = "" + if "desc" in dm: + desc = '/**< %s */' % dm["desc"] + + code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init; $desc') + + if self.isMessage: + code('unsigned proc_id;') + + code.dedent() + code('};') + + code(''' +// Output operator declaration +ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj); + +// Output operator definition +extern inline +ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj) +{ + obj.print(out); + out << flush; + return out; +} + +#endif // ${{self.c_ident}}_H +''') + + code.write(path, "%s.hh" % self.c_ident) + + def printTypeCC(self, path): + code = code_formatter() + + code(''' +/** \\file ${{self.c_ident}}.cc + * + * Auto generated C++ code started by $__file__:$__line__ + */ + +#include "mem/protocol/${{self.c_ident}}.hh" +''') + + if self.isMessage: + code('Allocator<${{self.c_ident}}>* ${{self.c_ident}}::s_allocator_ptr = NULL;') + code(''' +/** \\brief Print the state of this object */ +void ${{self.c_ident}}::print(ostream& out) const +{ + out << "[${{self.c_ident}}: "; +''') + + # For each field + code.indent() + for dm in self.data_members.values(): + code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''') + + if self.isMessage: + code('out << "Time = " << getTime() << " ";') + code.dedent() + + # Trailer + code(''' + out << "]"; +}''') + + code.write(path, "%s.cc" % self.c_ident) + + def printEnumHH(self, path): + code = code_formatter() + code(''' +/** \\file ${{self.c_ident}}.hh + * + * Auto generated C++ code started by $__file__:$__line__ + */ +#ifndef ${{self.c_ident}}_H +#define ${{self.c_ident}}_H + +#include "mem/ruby/common/Global.hh" + +/** \\enum ${{self.c_ident}} + * \\brief ${{self.desc}} + */ +enum ${{self.c_ident}} { + ${{self.c_ident}}_FIRST, +''') + + code.indent() + # For each field + for i,(ident,enum) in enumerate(self.enums.iteritems()): + desc = enum.get("desc", "No description avaliable") + if i == 0: + init = ' = %s_FIRST' % self.c_ident + else: + init = '' + code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */') + code.dedent() + code(''' + ${{self.c_ident}}_NUM +}; +${{self.c_ident}} string_to_${{self.c_ident}}(const string& str); +string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); +${{self.c_ident}} &operator++(${{self.c_ident}} &e); +''') + + # MachineType hack used to set the base component id for each Machine + if self.isMachineType: + code(''' +int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj); +MachineType ${{self.c_ident}}_from_base_level(int); +int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj); +int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); +''') + + for enum in self.enums.itervalues(): + code('#define MACHINETYPE_${{enum.ident}} 1') + + # Trailer + code(''' +ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj); + +#endif // ${{self.c_ident}}_H +''') + + code.write(path, "%s.hh" % self.c_ident) + + def printEnumCC(self, path): + code = code_formatter() + code(''' +/** \\file ${{self.c_ident}}.hh + * + * Auto generated C++ code started by $__file__:$__line__ + */ + +#include "mem/protocol/${{self.c_ident}}.hh" + +''') + + if self.isMachineType: + code('#include "mem/protocol/ControllerFactory.hh"') + for enum in self.enums.itervalues(): + code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') + + code(''' +ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj) +{ + out << ${{self.c_ident}}_to_string(obj); + out << flush; + return out; +} + +string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj) +{ + switch(obj) { +''') + + # For each field + code.indent() + for enum in self.enums.itervalues(): + code(' case ${{self.c_ident}}_${{enum.ident}}:') + code(' return "${{enum.ident}}";') + code.dedent() + + # Trailer + code(''' + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return ""; + } +} + +${{self.c_ident}} string_to_${{self.c_ident}}(const string& str) +{ +''') + + # For each field + code.indent() + code("if (false) {") + start = "} else " + for enum in self.enums.itervalues(): + code('${start}if (str == "${{enum.ident}}") {') + code(' return ${{self.c_ident}}_${{enum.ident}};') + code.dedent() + + code(''' + } else { + WARN_EXPR(str); + ERROR_MSG("Invalid string conversion for type ${{self.c_ident}}"); + } +} + +${{self.c_ident}}& operator++(${{self.c_ident}}& e) { + assert(e < ${{self.c_ident}}_NUM); + return e = ${{self.c_ident}}(e+1); +} +''') + + # MachineType hack used to set the base level and number of + # components for each Machine + if self.isMachineType: + code(''' +/** \\brief returns the base vector index for each machine type to be used by NetDest + * + * \\return the base vector index for each machine type to be used by NetDest + * \\see NetDest.hh + */ +int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj) +{ + switch(obj) { +''') + + # For each field + code.indent() + for i,enum in enumerate(self.enums.itervalues()): + code(' case ${{self.c_ident}}_${{enum.ident}}:') + code(' return $i;') + code.dedent() + + # total num + code(''' + case ${{self.c_ident}}_NUM: + return ${{len(self.enums)}}; + + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return -1; + } +} + +/** \\brief returns the machine type for each base vector index used by NetDest + * + * \\return the MachineTYpe + */ +MachineType ${{self.c_ident}}_from_base_level(int type) +{ + switch(type) { +''') + + # For each field + code.indent() + for i,enum in enumerate(self.enums.itervalues()): + code(' case $i:') + code(' return ${{self.c_ident}}_${{enum.ident}};') + code.dedent() + + # Trailer + code(''' + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return MachineType_NUM; + } +} + +/** \\brief The return value indicates the number of components created + * before a particular machine\'s components + * + * \\return the base number of components for each machine + */ +int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) +{ + int base = 0; + switch(obj) { +''') + + # For each field + code.indent() + code(' case ${{self.c_ident}}_NUM:') + for enum in reversed(self.enums.values()): + code(' base += ${{enum.ident}}_Controller::getNumControllers();') + code(' case ${{self.c_ident}}_${{enum.ident}}:') + code(' break;') + code.dedent() + + code(''' + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return -1; + } + + return base; +} + +/** \\brief returns the total number of components for each machine + * \\return the total number of components for each machine + */ +int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) +{ + switch(obj) { +''') + + # For each field + for enum in self.enums.itervalues(): + code(''' + case ${{self.c_ident}}_${{enum.ident}}: + return ${{enum.ident}}_Controller::getNumControllers(); +''') + + # total num + code(''' + case ${{self.c_ident}}_NUM: + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return -1; + } +} +''') + + # Write the file + code.write(path, "%s.cc" % self.c_ident) + +__all__ = [ "Type" ] diff --git a/src/mem/slicc/symbols/Var.hh b/src/mem/slicc/symbols/Var.hh deleted file mode 100644 index 4cb504296..000000000 --- a/src/mem/slicc/symbols/Var.hh +++ /dev/null @@ -1,98 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Var.hh - * - * Description: - * - * $Id$ - * - * */ - -#ifndef VAR_H -#define VAR_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/symbols/Symbol.hh" -#include "mem/slicc/symbols/Type.hh" - -class StateMachine; - -class Var : public Symbol { -public: - // Constructors - Var(string id, const Location& location, - Type* type_ptr, string code, - const Map<string, string>& pairs, - StateMachine* machine_ptr = NULL); - - // Var(string id, const Location& location, - // Type* type_ptr, string code) : Symbol(id, location) { m_type_ptr = type_ptr; m_code = code; } - - // Destructor - ~Var() {} - - // Public Methods - string cIdent() const { return m_c_id; } - void writeCFiles(string path) {} - string getCode() const { return m_code; } - Type* getType() const { return m_type_ptr; } - StateMachine* getMachine() const { return m_machine_ptr; } - - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - Var(const Var& obj); - Var& operator=(const Var& obj); - - // Data Members (m_ prefix) - string m_c_id; - Type* m_type_ptr; - string m_code; - StateMachine* m_machine_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Var& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Var& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //VAR_H diff --git a/src/mem/slicc/symbols/Var.py b/src/mem/slicc/symbols/Var.py new file mode 100644 index 000000000..87a101f65 --- /dev/null +++ b/src/mem/slicc/symbols/Var.py @@ -0,0 +1,50 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class Var(Symbol): + def __init__(self, symtab, ident, location, type, code, pairs, + machine=None): + super(Var, self).__init__(symtab, ident, location, pairs) + + if machine: + self.c_ident = "%s_%s" % (machine, ident) + else: + self.c_ident = ident + + self.machine = machine + self.type = type + self.code = code + + def __repr__(self): + return "[Var id: %s]" % (self.c_ident) + + def writeCodeFiles(self, path): + pass + +__all__ = [ "Var" ] diff --git a/src/mem/slicc/symbols/__init__.py b/src/mem/slicc/symbols/__init__.py new file mode 100644 index 000000000..43388a5fe --- /dev/null +++ b/src/mem/slicc/symbols/__init__.py @@ -0,0 +1,38 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Nathan Binkert + +from slicc.symbols.Action import Action +from slicc.symbols.Event import Event +from slicc.symbols.Func import Func +from slicc.symbols.State import State +from slicc.symbols.StateMachine import StateMachine +from slicc.symbols.Symbol import Symbol +from slicc.symbols.SymbolTable import SymbolTable +from slicc.symbols.Transition import Transition +from slicc.symbols.Type import Type +from slicc.symbols.Var import Var diff --git a/src/mem/slicc/util.py b/src/mem/slicc/util.py new file mode 100644 index 000000000..abadc3e30 --- /dev/null +++ b/src/mem/slicc/util.py @@ -0,0 +1,75 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys + +def makeDir(path): + if os.path.exists(path): + if not os.path.isdir(path): + raise AttributeError, "%s exists but is not directory" % path + else: + os.mkdir(path) + +class PairContainer(object): + def __init__(self, pairs=None): + self.pairs = {} + if pairs: + self.pairs.update(pairs) + + def __contains__(self, item): + return item in self.pairs + + def __getitem__(self, item): + return self.pairs[item] + + def __setitem__(self, item, value): + self.pairs[item] = value + + def get(self, item, failobj=None): + return self.pairs.get(item, failobj) + +class Location(object): + def __init__(self, filename, lineno): + self.filename = filename + self.lineno = lineno + + def __str__(self): + return '%s:%d' % (os.path.basename(self.filename), self.lineno) + + def warning(self, message, *args): + if args: + message = message % args + #raise Exception, "%s: Warning: %s" % (self, message) + print >>sys.stderr, "%s: Warning: %s" % (self, message) + + def error(self, message, *args): + if args: + message = message % args + raise Exception, "%s: Error: %s" % (self, message) + sys.exit("\n%s: Error: %s" % (self, message)) + +__all__ = [ 'makeDir', 'PairContainer', 'Location' ] diff --git a/src/mem/translating_port.cc b/src/mem/translating_port.cc index 54de6625e..700229b23 100644 --- a/src/mem/translating_port.cc +++ b/src/mem/translating_port.cc @@ -30,7 +30,9 @@ */ #include <string> + #include "base/chunk_generator.hh" +#include "config/the_isa.hh" #include "mem/port.hh" #include "mem/translating_port.hh" #include "mem/page_table.hh" diff --git a/src/mem/vport.cc b/src/mem/vport.cc index 15be45c2a..ab061c019 100644 --- a/src/mem/vport.cc +++ b/src/mem/vport.cc @@ -34,6 +34,7 @@ */ #include "base/chunk_generator.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "mem/vport.hh" diff --git a/src/python/SConscript b/src/python/SConscript index bb892f376..935986a12 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -38,7 +38,6 @@ PySource('', 'importer.py') PySource('m5', 'm5/__init__.py') PySource('m5', 'm5/SimObject.py') PySource('m5', 'm5/config.py') -PySource('m5', 'm5/convert.py') PySource('m5', 'm5/core.py') PySource('m5', 'm5/debug.py') PySource('m5', 'm5/event.py') @@ -47,18 +46,18 @@ PySource('m5', 'm5/options.py') PySource('m5', 'm5/params.py') PySource('m5', 'm5/proxy.py') PySource('m5', 'm5/simulate.py') -PySource('m5', 'm5/smartdict.py') PySource('m5', 'm5/stats.py') PySource('m5', 'm5/ticks.py') PySource('m5', 'm5/trace.py') PySource('m5.util', 'm5/util/__init__.py') PySource('m5.util', 'm5/util/attrdict.py') PySource('m5.util', 'm5/util/code_formatter.py') +PySource('m5.util', 'm5/util/convert.py') PySource('m5.util', 'm5/util/grammar.py') PySource('m5.util', 'm5/util/jobfile.py') -PySource('m5.util', 'm5/util/misc.py') PySource('m5.util', 'm5/util/multidict.py') PySource('m5.util', 'm5/util/orderdict.py') +PySource('m5.util', 'm5/util/smartdict.py') SwigSource('m5.internal', 'swig/core.i') SwigSource('m5.internal', 'swig/debug.i') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 8ef22be4e..0e0ffaea9 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -31,47 +31,24 @@ import math import sys import types -import proxy -import m5 -from util import * - -# These utility functions have to come first because they're -# referenced in params.py... otherwise they won't be defined when we -# import params below, and the recursive import of this file from -# params.py will not find these names. -def isSimObject(value): - return isinstance(value, SimObject) - -def isSimObjectClass(value): - return issubclass(value, SimObject) - -def isSimObjectSequence(value): - if not isinstance(value, (list, tuple)) or len(value) == 0: - return False - - for val in value: - if not isNullPointer(val) and not isSimObject(val): - return False - - return True +try: + import pydot +except: + pydot = False -def isSimObjectOrSequence(value): - return isSimObject(value) or isSimObjectSequence(value) +import m5 +from m5.util import * # Have to import params up top since Param is referenced on initial # load (when SimObject class references Param to create a class # variable, the 'name' param)... -from params import * +from m5.params import * # There are a few things we need that aren't in params.__all__ since # normal users don't need them -from params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector -from proxy import * +from m5.params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector -noDot = False -try: - import pydot -except: - noDot = True +from m5.proxy import * +from m5.proxy import isproxy ##################################################################### # @@ -141,7 +118,7 @@ class MetaSimObject(type): # and only allow "private" attributes to be passed to the base # __new__ (starting with underscore). def __new__(mcls, name, bases, dict): - assert name not in allClasses + assert name not in allClasses, "SimObject %s already present" % name # Copy "private" attributes, functions, and classes to the # official dict. Everything else goes in _init_dict to be @@ -678,7 +655,7 @@ class SimObject(object): def unproxy_all(self): for param in self._params.iterkeys(): value = self._values.get(param) - if value != None and proxy.isproxy(value): + if value != None and isproxy(value): try: value = value.unproxy(self) except: @@ -749,8 +726,8 @@ class SimObject(object): for param in param_names: value = self._values.get(param) if value is None: - m5.fatal("%s.%s without default or user set value", - self.path(), param) + fatal("%s.%s without default or user set value", + self.path(), param) value = value.getValue() if isinstance(self._params[param], VectorParamDesc): @@ -886,6 +863,34 @@ def resolveSimObject(name): obj = instanceDict[name] return obj.getCCObject() +def isSimObject(value): + return isinstance(value, SimObject) + +def isSimObjectClass(value): + return issubclass(value, SimObject) + +def isSimObjectSequence(value): + if not isinstance(value, (list, tuple)) or len(value) == 0: + return False + + for val in value: + if not isNullPointer(val) and not isSimObject(val): + return False + + return True + +def isSimObjectOrSequence(value): + return isSimObject(value) or isSimObjectSequence(value) + +baseClasses = allClasses.copy() +baseInstances = instanceDict.copy() + +def clear(): + global allClasses, instanceDict + + allClasses = baseClasses.copy() + instanceDict = baseInstances.copy() + # __all__ defines the list of symbols that get exported when # 'from config import *' is invoked. Try to keep this reasonably # short to avoid polluting other namespaces. diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index c3512cd0d..9f9459ae8 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -25,106 +25,24 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Nathan Binkert -# Steve Reinhardt -import os -import sys +# Import useful subpackages of M5, but *only* when run as an m5 +# script. This is mostly to keep backward compatibility with existing +# scripts while allowing new SCons code to operate properly. -import smartdict - -# define a MaxTick parameter -MaxTick = 2**63 - 1 - -# define this here so we can use it right away if necessary - -def errorURL(prefix, s): - try: - import zlib - hashstr = "%x" % zlib.crc32(s) - except: - hashstr = "UnableToHash" - return "For more information see: http://www.m5sim.org/%s/%s" % \ - (prefix, hashstr) - - -# panic() should be called when something happens that should never -# ever happen regardless of what the user does (i.e., an acutal m5 -# bug). -def panic(fmt, *args): - print >>sys.stderr, 'panic:', fmt % args - print >>sys.stderr, errorURL('panic',fmt) - sys.exit(1) - -# fatal() should be called when the simulation cannot continue due to -# some condition that is the user's fault (bad configuration, invalid -# arguments, etc.) and not a simulator bug. -def fatal(fmt, *args): - print >>sys.stderr, 'fatal:', fmt % args - print >>sys.stderr, errorURL('fatal',fmt) - sys.exit(1) - -# force scalars to one-element lists for uniformity -def makeList(objOrList): - if isinstance(objOrList, list): - return objOrList - return [objOrList] - -# Prepend given directory to system module search path. We may not -# need this anymore if we can structure our config library more like a -# Python package. -def AddToPath(path): - # if it's a relative path and we know what directory the current - # python script is in, make the path relative to that directory. - if not os.path.isabs(path) and sys.path[0]: - path = os.path.join(sys.path[0], path) - path = os.path.realpath(path) - # sys.path[0] should always refer to the current script's directory, - # so place the new dir right after that. - sys.path.insert(1, path) - -# make a SmartDict out of the build options for our local use -build_env = smartdict.SmartDict() - -# make a SmartDict out of the OS environment too -env = smartdict.SmartDict() -env.update(os.environ) - -# Since we have so many mutual imports in this package, we should: -# 1. Put all intra-package imports at the *bottom* of the file, unless -# they're absolutely needed before that (for top-level statements -# or class attributes). Imports of "trivial" packages that don't -# import other packages (e.g., 'smartdict') can be at the top. -# 2. Never use 'from foo import *' on an intra-package import since -# you can get the wrong result if foo is only partially imported -# at the point you do that (i.e., because foo is in the middle of -# importing *you*). try: import internal except ImportError: internal = None -try: - import defines - build_env.update(defines.buildEnv) -except ImportError: - defines = None - if internal: - defines.compileDate = internal.core.compileDate - for k,v in internal.core.__dict__.iteritems(): - if k.startswith('flag_'): - setattr(defines, k[5:], v) + import SimObject + import core + import objects + import params + import stats + import util from event import * - from simulate import * from main import options, main - import stats - import core - -import SimObject -import params - -try: - import objects -except ImportError: - objects = None + from simulate import * diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 2a308ff09..29f8cc976 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -32,7 +32,7 @@ import os import socket import sys -from util import attrdict +from util import attrdict, fatal import config from options import OptionParser diff --git a/src/python/m5/params.py b/src/python/m5/params.py index edd78fa28..cf64070c5 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -50,13 +50,10 @@ import re import sys import time -import convert import proxy import ticks from util import * -import SimObject - def isSimObject(*args, **kwargs): return SimObject.isSimObject(*args, **kwargs) @@ -96,6 +93,8 @@ class ParamValue(object): # Regular parameter description. class ParamDesc(object): + file_ext = 'ptype' + def __init__(self, ptype_str, ptype, *args, **kwargs): self.ptype_str = ptype_str # remember ptype only if it is provided @@ -130,7 +129,7 @@ class ParamDesc(object): def __getattr__(self, attr): if attr == 'ptype': ptype = SimObject.allClasses[self.ptype_str] - assert issubclass(ptype, SimObject.SimObject) + assert isSimObjectClass(ptype) self.ptype = ptype return ptype @@ -185,6 +184,8 @@ class SimObjVector(VectorParamValue): v.print_ini(ini_file) class VectorParamDesc(ParamDesc): + file_ext = 'vptype' + # Convert assigned value to appropriate type. If the RHS is not a # list or tuple, it generates a single-element list. def convert(self, value): @@ -711,32 +712,31 @@ class MetaEnum(MetaParamValue): super(MetaEnum, cls).__init__(name, bases, init_dict) - def __str__(cls): - return cls.__name__ - # Generate C++ class declaration for this enum type. # Note that we wrap the enum in a class/struct to act as a namespace, # so that the enum strings can be brief w/o worrying about collisions. def cxx_decl(cls): - code = "#ifndef __ENUM__%s\n" % cls - code += '#define __ENUM__%s\n' % cls + name = cls.__name__ + code = "#ifndef __ENUM__%s\n" % name + code += '#define __ENUM__%s\n' % name code += '\n' code += 'namespace Enums {\n' - code += ' enum %s {\n' % cls + code += ' enum %s {\n' % name for val in cls.vals: code += ' %s = %d,\n' % (val, cls.map[val]) - code += ' Num_%s = %d,\n' % (cls, len(cls.vals)) + code += ' Num_%s = %d,\n' % (name, len(cls.vals)) code += ' };\n' - code += ' extern const char *%sStrings[Num_%s];\n' % (cls, cls) + code += ' extern const char *%sStrings[Num_%s];\n' % (name, name) code += '}\n' code += '\n' code += '#endif\n' return code def cxx_def(cls): - code = '#include "enums/%s.hh"\n' % cls + name = cls.__name__ + code = '#include "enums/%s.hh"\n' % name code += 'namespace Enums {\n' - code += ' const char *%sStrings[Num_%s] =\n' % (cls, cls) + code += ' const char *%sStrings[Num_%s] =\n' % (name, name) code += ' {\n' for val in cls.vals: code += ' "%s",\n' % val @@ -1170,6 +1170,15 @@ class PortParamDesc(object): ptype_str = 'Port' ptype = Port +baseEnums = allEnums.copy() +baseParams = allParams.copy() + +def clear(): + global allEnums, allParams + + allEnums = baseEnums.copy() + allParams = baseParams.copy() + __all__ = ['Param', 'VectorParam', 'Enum', 'Bool', 'String', 'Float', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', @@ -1184,3 +1193,5 @@ __all__ = ['Param', 'VectorParam', 'Time', 'NextEthernetAddr', 'NULL', 'Port', 'VectorPort'] + +import SimObject diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py index 45992fe85..092bd0339 100644 --- a/src/python/m5/simulate.py +++ b/src/python/m5/simulate.py @@ -40,6 +40,9 @@ import SimObject import ticks import objects +# define a MaxTick parameter +MaxTick = 2**63 - 1 + # The final hook to generate .ini files. Called from the user script # once the config is built. def instantiate(root): diff --git a/src/python/m5/ticks.py b/src/python/m5/ticks.py index 91834c9c8..181a65eba 100644 --- a/src/python/m5/ticks.py +++ b/src/python/m5/ticks.py @@ -41,7 +41,7 @@ def fixGlobalFrequency(): print "Global frequency set at %d ticks per second" % int(tps) def setGlobalFrequency(ticksPerSecond): - import convert + from m5.util import convert global tps, tps_fixed diff --git a/src/python/m5/trace.py b/src/python/m5/trace.py index 17aa6196c..db239040a 100644 --- a/src/python/m5/trace.py +++ b/src/python/m5/trace.py @@ -48,5 +48,5 @@ def help(): if flag == 'All': continue print " %s: %s" % (flag, flags.descriptions[flag]) - util.print_list(flags.compoundMap[flag], indent=8) + util.printList(flags.compoundMap[flag], indent=8) print diff --git a/src/python/m5/util/__init__.py b/src/python/m5/util/__init__.py index 3930c8b6f..7a674dd2d 100644 --- a/src/python/m5/util/__init__.py +++ b/src/python/m5/util/__init__.py @@ -1,4 +1,5 @@ -# Copyright (c) 2008 The Hewlett-Packard Development Company +# Copyright (c) 2008-2009 The Hewlett-Packard Development Company +# Copyright (c) 2004-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -26,14 +27,130 @@ # # Authors: Nathan Binkert +import os +import re +import sys + +import convert +import jobfile + from attrdict import attrdict, optiondict from code_formatter import code_formatter -from misc import * from multidict import multidict from orderdict import orderdict -import jobfile +from smartdict import SmartDict + +# define this here so we can use it right away if necessary +def errorURL(prefix, s): + try: + import zlib + hashstr = "%x" % zlib.crc32(s) + except: + hashstr = "UnableToHash" + return "For more information see: http://www.m5sim.org/%s/%s" % \ + (prefix, hashstr) + +# panic() should be called when something happens that should never +# ever happen regardless of what the user does (i.e., an acutal m5 +# bug). +def panic(fmt, *args): + print >>sys.stderr, 'panic:', fmt % args + print >>sys.stderr, errorURL('panic',fmt) + sys.exit(1) + +# fatal() should be called when the simulation cannot continue due to +# some condition that is the user's fault (bad configuration, invalid +# arguments, etc.) and not a simulator bug. +def fatal(fmt, *args): + print >>sys.stderr, 'fatal:', fmt % args + print >>sys.stderr, errorURL('fatal',fmt) + sys.exit(1) + +class Singleton(type): + def __call__(cls, *args, **kwargs): + if hasattr(cls, '_instance'): + return cls._instance + + cls._instance = super(Singleton, cls).__call__(*args, **kwargs) + return cls._instance + +def addToPath(path): + """Prepend given directory to system module search path. We may not + need this anymore if we can structure our config library more like a + Python package.""" + + # if it's a relative path and we know what directory the current + # python script is in, make the path relative to that directory. + if not os.path.isabs(path) and sys.path[0]: + path = os.path.join(sys.path[0], path) + path = os.path.realpath(path) + # sys.path[0] should always refer to the current script's directory, + # so place the new dir right after that. + sys.path.insert(1, path) + +# Apply method to object. +# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>) +def applyMethod(obj, meth, *args, **kwargs): + return getattr(obj, meth)(*args, **kwargs) -def print_list(items, indent=4): +# If the first argument is an (non-sequence) object, apply the named +# method with the given arguments. If the first argument is a +# sequence, apply the method to each element of the sequence (a la +# 'map'). +def applyOrMap(objOrSeq, meth, *args, **kwargs): + if not isinstance(objOrSeq, (list, tuple)): + return applyMethod(objOrSeq, meth, *args, **kwargs) + else: + return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] + +def compareVersions(v1, v2): + """helper function: compare arrays or strings of version numbers. + E.g., compare_version((1,3,25), (1,4,1)') + returns -1, 0, 1 if v1 is <, ==, > v2 + """ + def make_version_list(v): + if isinstance(v, (list,tuple)): + return v + elif isinstance(v, str): + return map(lambda x: int(re.match('\d+', x).group()), v.split('.')) + else: + raise TypeError + + v1 = make_version_list(v1) + v2 = make_version_list(v2) + # Compare corresponding elements of lists + for n1,n2 in zip(v1, v2): + if n1 < n2: return -1 + if n1 > n2: return 1 + # all corresponding values are equal... see if one has extra values + if len(v1) < len(v2): return -1 + if len(v1) > len(v2): return 1 + return 0 + +def crossproduct(items): + if len(items) == 1: + for i in items[0]: + yield (i,) + else: + for i in items[0]: + for j in crossproduct(items[1:]): + yield (i,) + j + +def flatten(items): + while items: + item = items.pop(0) + if isinstance(item, (list, tuple)): + items[0:0] = item + else: + yield item + +# force scalars to one-element lists for uniformity +def makeList(objOrList): + if isinstance(objOrList, list): + return objOrList + return [objOrList] + +def printList(items, indent=4): line = ' ' * indent for i,item in enumerate(items): if len(line) + len(item) > 76: @@ -45,3 +162,27 @@ def print_list(items, indent=4): else: line += item print line + +def readCommand(cmd, **kwargs): + """run the command cmd, read the results and return them + this is sorta like `cmd` in shell""" + from subprocess import Popen, PIPE, STDOUT + + if isinstance(cmd, str): + cmd = cmd.split() + + no_exception = 'exception' in kwargs + exception = kwargs.pop('exception', None) + + kwargs.setdefault('shell', False) + kwargs.setdefault('stdout', PIPE) + kwargs.setdefault('stderr', STDOUT) + kwargs.setdefault('close_fds', True) + try: + subp = Popen(cmd, **kwargs) + except Exception, e: + if no_exception: + return exception + raise + + return subp.communicate()[0] diff --git a/src/python/m5/util/attrdict.py b/src/python/m5/util/attrdict.py index 0b30258b9..8f7d59698 100644 --- a/src/python/m5/util/attrdict.py +++ b/src/python/m5/util/attrdict.py @@ -45,6 +45,12 @@ class attrdict(dict): return self.__delitem__(attr) return super(attrdict, self).__delattr__(attr) + def __getstate__(self): + return dict(self) + + def __setstate__(self, state): + self.update(state) + class multiattrdict(attrdict): """Wrap attrdict so that nested attribute accesses automatically create nested dictionaries.""" @@ -52,7 +58,7 @@ class multiattrdict(attrdict): try: return super(multiattrdict, self).__getattr__(attr) except AttributeError: - d = optiondict() + d = multiattrdict() setattr(self, attr, d) return d @@ -80,8 +86,12 @@ if __name__ == '__main__': print dir(x) print(x) + print + print "multiattrdict" x = multiattrdict() + x.x.x.x = 9 x.y.z = 9 print x print x.y print x.y.z + print x.z.z diff --git a/src/python/m5/util/code_formatter.py b/src/python/m5/util/code_formatter.py index 919a6423b..396fe0e52 100644 --- a/src/python/m5/util/code_formatter.py +++ b/src/python/m5/util/code_formatter.py @@ -24,6 +24,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import __builtin__ import inspect import os import re @@ -64,8 +65,8 @@ class lookup(object): if self.formatter.globals and item in self.frame.f_globals: return self.frame.f_globals[item] - if item in __builtins__: - return __builtins__[item] + if item in __builtin__.__dict__: + return __builtin__.__dict__[item] try: item = int(item) diff --git a/src/python/m5/convert.py b/src/python/m5/util/convert.py index bb9e3e1f1..bb9e3e1f1 100644 --- a/src/python/m5/convert.py +++ b/src/python/m5/util/convert.py diff --git a/src/python/m5/util/grammar.py b/src/python/m5/util/grammar.py index 93c2c84c4..ab5f35868 100644 --- a/src/python/m5/util/grammar.py +++ b/src/python/m5/util/grammar.py @@ -55,6 +55,7 @@ class Tokenizer(object): break yield tok self.input = _input() + self.lexer = lexer def next(self): return self.input.next() @@ -68,6 +69,9 @@ class Tokenizer(object): except StopIteration: return None + def __getattr__(self, attr): + return getattr(self.lexer, attr) + class Grammar(object): def __init__(self, output=None, debug=False): self.yacc_args = {} diff --git a/src/python/m5/util/jobfile.py b/src/python/m5/util/jobfile.py index c830895f6..9c59778e5 100644 --- a/src/python/m5/util/jobfile.py +++ b/src/python/m5/util/jobfile.py @@ -28,9 +28,6 @@ import sys -from attrdict import optiondict -from misc import crossproduct - class Data(object): def __init__(self, name, desc, **kwargs): self.name = name @@ -108,7 +105,8 @@ class Data(object): yield key def optiondict(self): - result = optiondict() + import m5.util + result = m5.util.optiondict() for key in self: result[key] = self[key] return result @@ -328,7 +326,9 @@ class Configuration(Data): optgroups = [ g.subopts() for g in groups ] if not optgroups: return - for options in crossproduct(optgroups): + + import m5.util + for options in m5.util.crossproduct(optgroups): for opt in options: cpt = opt._group._checkpoint if not isinstance(cpt, bool) and cpt != opt: diff --git a/src/python/m5/util/misc.py b/src/python/m5/util/misc.py deleted file mode 100644 index 094e3ed9a..000000000 --- a/src/python/m5/util/misc.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (c) 2004-2006 The Regents of The University of Michigan -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Steve Reinhardt -# Nathan Binkert - -############################# -# -# Utility classes & methods -# -############################# - -class Singleton(type): - def __call__(cls, *args, **kwargs): - if hasattr(cls, '_instance'): - return cls._instance - - cls._instance = super(Singleton, cls).__call__(*args, **kwargs) - return cls._instance - -# Apply method to object. -# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>) -def applyMethod(obj, meth, *args, **kwargs): - return getattr(obj, meth)(*args, **kwargs) - -# If the first argument is an (non-sequence) object, apply the named -# method with the given arguments. If the first argument is a -# sequence, apply the method to each element of the sequence (a la -# 'map'). -def applyOrMap(objOrSeq, meth, *args, **kwargs): - if not isinstance(objOrSeq, (list, tuple)): - return applyMethod(objOrSeq, meth, *args, **kwargs) - else: - return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] - -def crossproduct(items): - if not isinstance(items, (list, tuple)): - raise AttributeError, 'crossproduct works only on sequences' - - if not items: - yield None - return - - current = items[0] - remainder = items[1:] - - if not hasattr(current, '__iter__'): - current = [ current ] - - for item in current: - for rem in crossproduct(remainder): - data = [ item ] - if rem: - data += rem - yield data - -def flatten(items): - if not isinstance(items, (list, tuple)): - yield items - return - - for item in items: - for flat in flatten(item): - yield flat diff --git a/src/python/m5/smartdict.py b/src/python/m5/util/smartdict.py index d85dbd517..d85dbd517 100644 --- a/src/python/m5/smartdict.py +++ b/src/python/m5/util/smartdict.py diff --git a/src/sim/System.py b/src/sim/System.py index 3b0bc1e46..06a54a78d 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -27,9 +27,10 @@ # Authors: Nathan Binkert from m5.SimObject import SimObject +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env + from PhysicalMemory import * class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing'] @@ -40,7 +41,7 @@ class System(SimObject): physmem = Param.PhysicalMemory(Parent.any, "physical memory") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: abstract = True boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency, "boot processor frequency") diff --git a/src/sim/arguments.cc b/src/sim/arguments.cc index 5aa57755a..339a57f90 100644 --- a/src/sim/arguments.cc +++ b/src/sim/arguments.cc @@ -28,11 +28,10 @@ * Authors: Nathan Binkert */ -#include "sim/arguments.hh" #include "arch/utility.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" - -using namespace TheISA; +#include "sim/arguments.hh" Arguments::Data::~Data() { diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 29efdeb6f..92c38142c 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -471,7 +471,7 @@ class EventWrapper : public Event inline void EventQueue::schedule(Event *event, Tick when) { - assert(when >= curTick); + assert((UTick)when >= (UTick)curTick); assert(!event->scheduled()); #ifdef EVENTQ_DEBUG assert((event->flags & Event::Initialized) == Event::Initialized); diff --git a/src/sim/process.cc b/src/sim/process.cc index 55bd2f209..343d2ad5a 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -32,6 +32,8 @@ #include <unistd.h> #include <fcntl.h> + +#include <cstdio> #include <string> #include "arch/remote_gdb.hh" @@ -40,6 +42,7 @@ #include "base/loader/symtab.hh" #include "base/statistics.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "mem/page_table.hh" #include "mem/physical.hh" @@ -53,7 +56,6 @@ #include "sim/syscall_emul.hh" #include "sim/system.hh" -#include "arch/isa_specific.hh" #if THE_ISA == ALPHA_ISA #include "arch/alpha/linux/process.hh" #include "arch/alpha/tru64/process.hh" @@ -66,6 +68,8 @@ #include "arch/arm/linux/process.hh" #elif THE_ISA == X86_ISA #include "arch/x86/linux/process.hh" +#elif THE_ISA == POWER_ISA +#include "arch/power/linux/process.hh" #else #error "THE_ISA not set" #endif @@ -626,7 +630,7 @@ LiveProcess::argsInit(int intSize, int pageSize) tc->setPC(prog_entry); tc->setNextPC(prog_entry + sizeof(MachInst)); -#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc +#if THE_ISA != ALPHA_ISA && THE_ISA != POWER_ISA //e.g. MIPS or Sparc tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); #endif @@ -645,6 +649,12 @@ LiveProcess::syscall(int64_t callnum, ThreadContext *tc) desc->doSyscall(callnum, this, tc); } +IntReg +LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width) +{ + return getSyscallArg(tc, i); +} + LiveProcess * LiveProcess::create(LiveProcessParams * params) { @@ -754,6 +764,20 @@ LiveProcess::create(LiveProcessParams * params) default: fatal("Unknown/unsupported operating system."); } +#elif THE_ISA == POWER_ISA + if (objFile->getArch() != ObjectFile::Power) + fatal("Object file architecture does not match compiled ISA (Power)."); + switch (objFile->getOpSys()) { + case ObjectFile::UnknownOpSys: + warn("Unknown operating system; assuming Linux."); + // fall through + case ObjectFile::Linux: + process = new PowerLinuxProcess(params, objFile); + break; + + default: + fatal("Unknown/unsupported operating system."); + } #else #error "THE_ISA not set" #endif diff --git a/src/sim/process.hh b/src/sim/process.hh index 05a48071a..ab9d64cf3 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -47,9 +47,11 @@ #include "arch/registers.hh" #include "base/statistics.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "sim/sim_object.hh" #include "sim/syscallreturn.hh" +class BaseRemoteGDB; class GDBListener; class PageTable; class ProcessParams; @@ -58,10 +60,6 @@ class SyscallDesc; class System; class ThreadContext; class TranslatingPort; -namespace TheISA -{ - class RemoteGDB; -} template<class IntType> struct AuxVector @@ -94,7 +92,7 @@ class Process : public SimObject std::vector<int> contextIds; // remote gdb objects - std::vector<TheISA::RemoteGDB *> remoteGDB; + std::vector<BaseRemoteGDB *> remoteGDB; std::vector<GDBListener *> gdbListen; bool breakpoint(); @@ -327,7 +325,9 @@ class LiveProcess : public Process std::string getcwd() const { return cwd; } virtual void syscall(int64_t callnum, ThreadContext *tc); - virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int i) = 0; + + virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0; + virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width); virtual void setSyscallArg(ThreadContext *tc, int i, TheISA::IntReg val) = 0; virtual void setSyscallReturn(ThreadContext *tc, diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 6182150d4..cf063818b 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -35,10 +35,10 @@ #include <fstream> #include <string> -#include "config/full_system.hh" - #include "arch/vtophys.hh" #include "base/debug.hh" +#include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "cpu/quiesce_event.hh" diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 811bdb73a..4726decc5 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -32,18 +32,19 @@ #include <fcntl.h> #include <unistd.h> -#include <string> +#include <cstdio> #include <iostream> +#include <string> #include "sim/syscall_emul.hh" #include "base/chunk_generator.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "mem/page_table.hh" #include "sim/process.hh" #include "sim/system.hh" - #include "sim/sim_exit.hh" using namespace std; @@ -52,11 +53,16 @@ using namespace TheISA; void SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc) { +#if TRACING_ON + int index = 0; +#endif DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", curTick, tc->getCpuPtr()->name(), name, - process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1), - process->getSyscallArg(tc, 2), process->getSyscallArg(tc, 3)); + process->getSyscallArg(tc, index), + process->getSyscallArg(tc, index), + process->getSyscallArg(tc, index), + process->getSyscallArg(tc, index)); SyscallReturn retval = (*funcPtr)(this, callnum, process, tc); @@ -82,8 +88,9 @@ SyscallReturn ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { + int index = 0; warn("ignoring syscall %s(%d, %d, ...)", desc->name, - process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1)); + process->getSyscallArg(tc, index), process->getSyscallArg(tc, index)); return 0; } @@ -95,8 +102,9 @@ exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { if (process->system->numRunningContexts() == 1) { // Last running context... exit simulator + int index = 0; exitSimLoop("target called exit()", - process->getSyscallArg(tc, 0) & 0xff); + process->getSyscallArg(tc, index) & 0xff); } else { // other running threads... just halt this one tc->halt(); @@ -112,8 +120,9 @@ exitGroupFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { // really should just halt all thread contexts belonging to this // process in case there's another process running... + int index = 0; exitSimLoop("target called exit()", - process->getSyscallArg(tc, 0) & 0xff); + process->getSyscallArg(tc, index) & 0xff); return 1; } @@ -130,7 +139,8 @@ SyscallReturn brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { // change brk addr to first arg - Addr new_brk = p->getSyscallArg(tc, 0); + int index = 0; + Addr new_brk = p->getSyscallArg(tc, index); // in Linux at least, brk(0) returns the current break value // (note that the syscall and the glibc function have different behavior) @@ -144,6 +154,24 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) if (!p->pTable->translate(gen.addr())) p->pTable->allocate(roundDown(gen.addr(), VMPageSize), VMPageSize); + + // if the address is already there, zero it out + else { + uint8_t zero = 0; + TranslatingPort *tp = tc->getMemPort(); + + // split non-page aligned accesses + Addr next_page = roundUp(gen.addr(), VMPageSize); + uint32_t size_needed = next_page - gen.addr(); + tp->memsetBlob(gen.addr(), zero, size_needed); + if (gen.addr() + VMPageSize > next_page && + next_page < new_brk && + p->pTable->translate(next_page)) + { + size_needed = VMPageSize - size_needed; + tp->memsetBlob(next_page, zero, size_needed); + } + } } } @@ -156,7 +184,8 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int target_fd = p->getSyscallArg(tc, 0); + int index = 0; + int target_fd = p->getSyscallArg(tc, index); int status = close(p->sim_fd(target_fd)); if (status >= 0) p->free_fd(target_fd); @@ -167,9 +196,11 @@ closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(p->getSyscallArg(tc, 0)); - int nbytes = p->getSyscallArg(tc, 2); - BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes); + int index = 0; + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + Addr bufPtr = p->getSyscallArg(tc, index); + int nbytes = p->getSyscallArg(tc, index); + BufferArg bufArg(bufPtr, nbytes); int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); @@ -182,9 +213,11 @@ readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(p->getSyscallArg(tc, 0)); - int nbytes = p->getSyscallArg(tc, 2); - BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes); + int index = 0; + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + Addr bufPtr = p->getSyscallArg(tc, index); + int nbytes = p->getSyscallArg(tc, index); + BufferArg bufArg(bufPtr, nbytes); bufArg.copyIn(tc->getMemPort()); @@ -199,9 +232,10 @@ writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(p->getSyscallArg(tc, 0)); - uint64_t offs = p->getSyscallArg(tc, 1); - int whence = p->getSyscallArg(tc, 2); + int index = 0; + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + uint64_t offs = p->getSyscallArg(tc, index); + int whence = p->getSyscallArg(tc, index); off_t result = lseek(fd, offs, whence); @@ -212,11 +246,12 @@ lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn _llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(p->getSyscallArg(tc, 0)); - uint64_t offset_high = p->getSyscallArg(tc, 1); - uint32_t offset_low = p->getSyscallArg(tc, 2); - Addr result_ptr = p->getSyscallArg(tc, 3); - int whence = p->getSyscallArg(tc, 4); + int index = 0; + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + uint64_t offset_high = p->getSyscallArg(tc, index); + uint32_t offset_low = p->getSyscallArg(tc, index); + Addr result_ptr = p->getSyscallArg(tc, index); + int whence = p->getSyscallArg(tc, index); uint64_t offset = (offset_high << 32) | offset_low; @@ -255,8 +290,10 @@ const char *hostname = "m5.eecs.umich.edu"; SyscallReturn gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int name_len = p->getSyscallArg(tc, 1); - BufferArg name(p->getSyscallArg(tc, 0), name_len); + int index = 0; + Addr bufPtr = p->getSyscallArg(tc, index); + int name_len = p->getSyscallArg(tc, index); + BufferArg name(bufPtr, name_len); strncpy((char *)name.bufferPtr(), hostname, name_len); @@ -269,8 +306,10 @@ SyscallReturn getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { int result = 0; - unsigned long size = p->getSyscallArg(tc, 1); - BufferArg buf(p->getSyscallArg(tc, 0), size); + int index = 0; + Addr bufPtr = p->getSyscallArg(tc, index); + unsigned long size = p->getSyscallArg(tc, index); + BufferArg buf(bufPtr, size); // Is current working directory defined? string cwd = p->getcwd(); @@ -302,14 +341,17 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return (TheISA::IntReg)-EFAULT; // Adjust path for current working directory path = p->fullPath(path); - size_t bufsiz = p->getSyscallArg(tc, 2); - BufferArg buf(p->getSyscallArg(tc, 1), bufsiz); + Addr bufPtr = p->getSyscallArg(tc, index); + size_t bufsiz = p->getSyscallArg(tc, index); + + BufferArg buf(bufPtr, bufsiz); int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz); @@ -323,7 +365,8 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return (TheISA::IntReg)-EFAULT; // Adjust path for current working directory @@ -339,13 +382,14 @@ mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return (TheISA::IntReg)-EFAULT; // Adjust path for current working directory path = p->fullPath(path); - mode_t mode = p->getSyscallArg(tc, 1); + mode_t mode = p->getSyscallArg(tc, index); int result = mkdir(path.c_str(), mode); return (result == -1) ? -errno : result; @@ -356,12 +400,13 @@ renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string old_name; - if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, index))) return -EFAULT; string new_name; - if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, 1))) + if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, index))) return -EFAULT; // Adjust path for current working directory @@ -377,10 +422,11 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return -EFAULT; - off_t length = p->getSyscallArg(tc, 1); + off_t length = p->getSyscallArg(tc, index); // Adjust path for current working directory path = p->fullPath(path); @@ -393,18 +439,62 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); if (fd < 0) return -EBADF; - off_t length = process->getSyscallArg(tc, 1); + off_t length = process->getSyscallArg(tc, index); int result = ftruncate(fd, length); return (result == -1) ? -errno : result; } SyscallReturn +truncate64Func(SyscallDesc *desc, int num, + LiveProcess *process, ThreadContext *tc) +{ + int index = 0; + string path; + + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, index))) + return -EFAULT; + + int64_t length = process->getSyscallArg(tc, index, 64); + + // Adjust path for current working directory + path = process->fullPath(path); + +#if NO_STAT64 + int result = truncate(path.c_str(), length); +#else + int result = truncate64(path.c_str(), length); +#endif + return (result == -1) ? -errno : result; +} + +SyscallReturn +ftruncate64Func(SyscallDesc *desc, int num, + LiveProcess *process, ThreadContext *tc) +{ + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); + + if (fd < 0) + return -EBADF; + + int64_t length = process->getSyscallArg(tc, index, 64); + +#if NO_STAT64 + int result = ftruncate(fd, length); +#else + int result = ftruncate64(fd, length); +#endif + return (result == -1) ? -errno : result; +} + +SyscallReturn umaskFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { // Letting the simulated program change the simulator's umask seems like @@ -420,13 +510,14 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return -EFAULT; /* XXX endianess */ - uint32_t owner = p->getSyscallArg(tc, 1); + uint32_t owner = p->getSyscallArg(tc, index); uid_t hostOwner = owner; - uint32_t group = p->getSyscallArg(tc, 2); + uint32_t group = p->getSyscallArg(tc, index); gid_t hostGroup = group; // Adjust path for current working directory @@ -439,15 +530,16 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); if (fd < 0) return -EBADF; /* XXX endianess */ - uint32_t owner = process->getSyscallArg(tc, 1); + uint32_t owner = process->getSyscallArg(tc, index); uid_t hostOwner = owner; - uint32_t group = process->getSyscallArg(tc, 2); + uint32_t group = process->getSyscallArg(tc, index); gid_t hostGroup = group; int result = fchown(fd, hostOwner, hostGroup); @@ -458,11 +550,12 @@ fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) SyscallReturn dupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); if (fd < 0) return -EBADF; - Process::FdMap *fdo = process->sim_fd_obj(process->getSyscallArg(tc, 0)); + Process::FdMap *fdo = process->sim_fd_obj(fd); int result = dup(fd); return (result == -1) ? -errno : @@ -474,12 +567,13 @@ SyscallReturn fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) return -EBADF; - int cmd = process->getSyscallArg(tc, 1); + int cmd = process->getSyscallArg(tc, index); switch (cmd) { case 0: // F_DUPFD // if we really wanted to support this, we'd need to do it @@ -516,12 +610,13 @@ SyscallReturn fcntl64Func(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) return -EBADF; - int cmd = process->getSyscallArg(tc, 1); + int cmd = process->getSyscallArg(tc, index); switch (cmd) { case 33: //F_GETLK64 warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd); @@ -605,7 +700,8 @@ setuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { // can't fathom why a benchmark would call this. - warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, 0)); + int index = 0; + warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, index)); return 0; } @@ -661,17 +757,20 @@ SyscallReturn cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { + int index = 0; + IntReg flags = process->getSyscallArg(tc, index); + IntReg newStack = process->getSyscallArg(tc, index); + DPRINTF(SyscallVerbose, "In sys_clone:\n"); - DPRINTF(SyscallVerbose, " Flags=%llx\n", process->getSyscallArg(tc, 0)); - DPRINTF(SyscallVerbose, " Child stack=%llx\n", - process->getSyscallArg(tc, 1)); + DPRINTF(SyscallVerbose, " Flags=%llx\n", flags); + DPRINTF(SyscallVerbose, " Child stack=%llx\n", newStack); - if (process->getSyscallArg(tc, 0) != 0x10f00) { + if (flags != 0x10f00) { warn("This sys_clone implementation assumes flags " "CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD " "(0x10f00), and may not work correctly with given flags " - "0x%llx\n", process->getSyscallArg(tc, 0)); + "0x%llx\n", flags); } ThreadContext* ctc; // child thread context @@ -704,7 +803,7 @@ cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process, #endif // Set up stack register - ctc->setIntReg(TheISA::StackPointerReg, process->getSyscallArg(tc, 1)); + ctc->setIntReg(TheISA::StackPointerReg, newStack); // Set up syscall return values in parent and child ctc->setIntReg(ReturnValueReg, 0); // return value, child diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 5f2ebd428..66e800183 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -55,10 +55,12 @@ #include "base/misc.hh" #include "base/trace.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "mem/translating_port.hh" #include "mem/page_table.hh" +#include "sim/system.hh" #include "sim/process.hh" /// @@ -258,6 +260,15 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); +/// Target truncate64() handler. +SyscallReturn truncate64Func(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + +/// Target ftruncate64() handler. +SyscallReturn ftruncate64Func(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + + /// Target umask() handler. SyscallReturn umaskFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); @@ -462,7 +473,7 @@ copyOutStat64Buf(TranslatingPort * mem, Addr addr, { typedef TypedBufferArg<typename OS::tgt_stat64> tgt_stat_buf; tgt_stat_buf tgt(addr); - convertStatBuf<tgt_stat_buf, hst_stat64>(tgt, host, fakeTTY); + convertStat64Buf<tgt_stat_buf, hst_stat64>(tgt, host, fakeTTY); tgt.copyOut(mem); } @@ -474,8 +485,9 @@ SyscallReturn ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); - unsigned req = process->getSyscallArg(tc, 1); + int index = 0; + int fd = process->getSyscallArg(tc, index); + unsigned req = process->getSyscallArg(tc, index); DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); @@ -493,6 +505,7 @@ ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, case OS::TIOCGETC_: case OS::TIOCGETS_: case OS::TIOCGETA_: + case OS::TCSETAW_: return -ENOTTY; default: @@ -509,7 +522,9 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) return -EFAULT; if (path == "/dev/sysdev0") { @@ -519,8 +534,8 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return -ENOENT; } - int tgtFlags = process->getSyscallArg(tc, 1); - int mode = process->getSyscallArg(tc, 2); + int tgtFlags = process->getSyscallArg(tc, index); + int mode = process->getSyscallArg(tc, index); int hostFlags = 0; // translate open flags @@ -558,6 +573,24 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } +/// Target sysinfo() handler. +template <class OS> +SyscallReturn +sysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + + int index = 0; + TypedBufferArg<typename OS::tgt_sysinfo> + sysinfo(process->getSyscallArg(tc, index)); + + sysinfo->uptime=seconds_since_epoch; + sysinfo->totalram=process->system->memSize(); + + sysinfo.copyOut(tc->getMemPort()); + + return 0; +} /// Target chmod() handler. template <class OS> @@ -567,10 +600,13 @@ chmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { return -EFAULT; + } - uint32_t mode = process->getSyscallArg(tc, 1); + uint32_t mode = process->getSyscallArg(tc, index); mode_t hostMode = 0; // XXX translate mode flags via OS::something??? @@ -594,13 +630,14 @@ SyscallReturn fchmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; } - uint32_t mode = process->getSyscallArg(tc, 1); + uint32_t mode = process->getSyscallArg(tc, index); mode_t hostMode = 0; // XXX translate mode flags via OS::someting??? @@ -619,10 +656,11 @@ template <class OS> SyscallReturn mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr start = process->getSyscallArg(tc, 0); - uint64_t old_length = process->getSyscallArg(tc, 1); - uint64_t new_length = process->getSyscallArg(tc, 2); - uint64_t flags = process->getSyscallArg(tc, 3); + int index = 0; + Addr start = process->getSyscallArg(tc, index); + uint64_t old_length = process->getSyscallArg(tc, index); + uint64_t new_length = process->getSyscallArg(tc, index); + uint64_t flags = process->getSyscallArg(tc, index); if ((start % TheISA::VMPageSize != 0) || (new_length % TheISA::VMPageSize != 0)) { @@ -668,8 +706,12 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -680,8 +722,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -695,8 +736,11 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) return -EFAULT; + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -712,8 +756,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -725,7 +768,9 @@ SyscallReturn fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; @@ -742,8 +787,7 @@ fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf, (fd == 1)); + copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1)); return 0; } @@ -757,8 +801,12 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -769,8 +817,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -783,8 +830,12 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -800,8 +851,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -812,7 +862,9 @@ SyscallReturn fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); + Addr bufPtr = process->getSyscallArg(tc, index); DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); @@ -825,8 +877,7 @@ fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf, (fd == 1)); + copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1)); return 0; } @@ -840,8 +891,12 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -852,8 +907,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - OS::copyOutStatfsBuf(tc->getMemPort(), - (Addr)(process->getSyscallArg(tc, 1)), &hostBuf); + OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -865,7 +919,9 @@ SyscallReturn fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); + Addr bufPtr = process->getSyscallArg(tc, index); if (fd < 0) return -EBADF; @@ -876,8 +932,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - OS::copyOutStatfsBuf(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -889,15 +944,16 @@ SyscallReturn writevFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; } TranslatingPort *p = tc->getMemPort(); - uint64_t tiov_base = process->getSyscallArg(tc, 1); - size_t count = process->getSyscallArg(tc, 2); + uint64_t tiov_base = process->getSyscallArg(tc, index); + size_t count = process->getSyscallArg(tc, index); struct iovec hiov[count]; for (size_t i = 0; i < count; ++i) { typename OS::tgt_iovec tiov; @@ -938,12 +994,13 @@ template <class OS> SyscallReturn mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - Addr start = p->getSyscallArg(tc, 0); - uint64_t length = p->getSyscallArg(tc, 1); - // int prot = p->getSyscallArg(tc, 2); - int flags = p->getSyscallArg(tc, 3); - // int fd = p->sim_fd(p->getSyscallArg(tc, 4)); - // int offset = p->getSyscallArg(tc, 5); + int index = 0; + Addr start = p->getSyscallArg(tc, index); + uint64_t length = p->getSyscallArg(tc, index); + index++; // int prot = p->getSyscallArg(tc, index); + int flags = p->getSyscallArg(tc, index); + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + // int offset = p->getSyscallArg(tc, index); if ((start % TheISA::VMPageSize) != 0 || @@ -960,13 +1017,18 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) } // pick next address from our "mmap region" - start = p->mmap_end; + if (OS::mmapGrowsDown()) { + start = p->mmap_end - length; + p->mmap_end = start; + } else { + start = p->mmap_end; + p->mmap_end += length; + } p->pTable->allocate(start, length); - p->mmap_end += length; if (!(flags & OS::TGT_MAP_ANONYMOUS)) { warn("allowing mmap of file @ fd %d. " - "This will break if not /dev/zero.", p->getSyscallArg(tc, 4)); + "This will break if not /dev/zero.", fd); } return start; @@ -978,8 +1040,9 @@ SyscallReturn getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned resource = process->getSyscallArg(tc, 0); - TypedBufferArg<typename OS::rlimit> rlp(process->getSyscallArg(tc, 1)); + int index = 0; + unsigned resource = process->getSyscallArg(tc, index); + TypedBufferArg<typename OS::rlimit> rlp(process->getSyscallArg(tc, index)); switch (resource) { case OS::TGT_RLIMIT_STACK: @@ -1013,7 +1076,8 @@ SyscallReturn gettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, index)); getElapsedTime(tp->tv_sec, tp->tv_usec); tp->tv_sec += seconds_since_epoch; @@ -1034,10 +1098,14 @@ utimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } - TypedBufferArg<typename OS::timeval [2]> tp(process->getSyscallArg(tc, 1)); + TypedBufferArg<typename OS::timeval [2]> + tp(process->getSyscallArg(tc, index)); tp.copyIn(tc->getMemPort()); struct timeval hostTimeval[2]; @@ -1063,8 +1131,9 @@ SyscallReturn getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int who = process->getSyscallArg(tc, 0); // THREAD, SELF, or CHILDREN - TypedBufferArg<typename OS::rusage> rup(process->getSyscallArg(tc, 1)); + int index = 0; + int who = process->getSyscallArg(tc, index); // THREAD, SELF, or CHILDREN + TypedBufferArg<typename OS::rusage> rup(process->getSyscallArg(tc, index)); rup->ru_utime.tv_sec = 0; rup->ru_utime.tv_usec = 0; @@ -1108,7 +1177,52 @@ getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return 0; } +/// Target times() function. +template <class OS> +SyscallReturn +timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + int index = 0; + TypedBufferArg<typename OS::tms> bufp(process->getSyscallArg(tc, index)); + + // Fill in the time structure (in clocks) + int64_t clocks = curTick * OS::M5_SC_CLK_TCK / Clock::Int::s; + bufp->tms_utime = clocks; + bufp->tms_stime = 0; + bufp->tms_cutime = 0; + bufp->tms_cstime = 0; + // Convert to host endianness + bufp->tms_utime = htog(bufp->tms_utime); + + // Write back + bufp.copyOut(tc->getMemPort()); + + // Return clock ticks since system boot + return clocks; +} + +/// Target time() function. +template <class OS> +SyscallReturn +timeFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + typename OS::time_t sec, usec; + getElapsedTime(sec, usec); + sec += seconds_since_epoch; + + int index = 0; + Addr taddr = (Addr)process->getSyscallArg(tc, index); + if(taddr != 0) { + typename OS::time_t t = sec; + t = htog(t); + TranslatingPort *p = tc->getMemPort(); + p->writeBlob(taddr, (uint8_t*)&t, (int)sizeof(typename OS::time_t)); + } + return sec; +} #endif // __SIM_SYSCALL_EMUL_HH__ diff --git a/src/sim/system.cc b/src/sim/system.cc index f10167bba..da77f1995 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -38,11 +38,14 @@ #include "base/loader/symtab.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" +#include "config/full_system.hh" +#include "config/the_isa.hh" #include "mem/mem_object.hh" #include "mem/physical.hh" #include "sim/byteswap.hh" #include "sim/system.hh" #include "sim/debug.hh" + #if FULL_SYSTEM #include "arch/vtophys.hh" #include "kern/kernel_stats.hh" diff --git a/src/sim/system.hh b/src/sim/system.hh index aa89866bd..eabbc8351 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -45,6 +45,7 @@ #include "mem/port.hh" #include "params/System.hh" #include "sim/sim_object.hh" + #if FULL_SYSTEM #include "kern/system_events.hh" #include "mem/vport.hh" @@ -59,10 +60,7 @@ class PhysicalMemory; class Platform; #endif class GDBListener; -namespace TheISA -{ - class RemoteGDB; -} +class BaseRemoteGDB; class System : public SimObject { @@ -187,7 +185,7 @@ class System : public SimObject #endif public: - std::vector<TheISA::RemoteGDB *> remoteGDB; + std::vector<BaseRemoteGDB *> remoteGDB; std::vector<GDBListener *> gdbListen; bool breakpoint(); diff --git a/tests/configs/inorder-timing.py b/tests/configs/inorder-timing.py index 62f8b5850..10f9e4232 100644 --- a/tests/configs/inorder-timing.py +++ b/tests/configs/inorder-timing.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') class MyCache(BaseCache): assoc = 2 diff --git a/tests/configs/o3-timing-mp-ruby.py b/tests/configs/o3-timing-mp-ruby.py index eab9bfaf2..77e1ba992 100644 --- a/tests/configs/o3-timing-mp-ruby.py +++ b/tests/configs/o3-timing-mp-ruby.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') nb_cores = 4 cpus = [ DerivO3CPU(cpu_id=i) for i in xrange(nb_cores) ] diff --git a/tests/configs/o3-timing-mp.py b/tests/configs/o3-timing-mp.py index fc6a72a82..59776d5c3 100644 --- a/tests/configs/o3-timing-mp.py +++ b/tests/configs/o3-timing-mp.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') # -------------------- # Base L1 Cache diff --git a/tests/configs/o3-timing-ruby.py b/tests/configs/o3-timing-ruby.py index a91a9cf39..f7ad41d99 100644 --- a/tests/configs/o3-timing-ruby.py +++ b/tests/configs/o3-timing-ruby.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import ruby_config diff --git a/tests/configs/o3-timing.py b/tests/configs/o3-timing.py index 366a3eb0d..563772213 100644 --- a/tests/configs/o3-timing.py +++ b/tests/configs/o3-timing.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') class MyCache(BaseCache): assoc = 2 diff --git a/tests/configs/ruby_config.py b/tests/configs/ruby_config.py index 7b8e27613..190337e67 100644 --- a/tests/configs/ruby_config.py +++ b/tests/configs/ruby_config.py @@ -4,17 +4,27 @@ import subprocess from os.path import dirname, join as joinpath import m5 +from m5.params import * -def generate(config_file, cores=1, memories=1, memory_size=1024): +def generate(config_file, cores=1, memories=1, memory_size=1024, \ + cache_size=32768, cache_assoc=8, dmas=1, + ruby_tick='1t', ports_per_cpu=2, protocol='MOESI_CMP_directory'): default = joinpath(dirname(__file__), '../../src/mem/ruby/config') ruby_config = os.environ.get('RUBY_CONFIG', default) args = [ "ruby", "-I", ruby_config, joinpath(ruby_config, "print_cfg.rb"), + "-c", str(protocol), "-r", joinpath(ruby_config, config_file), "-p", str(cores), - "-m", str(memories), "-s", str(memory_size)] + "-m", str(memories), "-s", str(memory_size), "-C", str(cache_size), + "-A", str(cache_assoc), "-D", str(dmas)] temp_config = joinpath(m5.options.outdir, "ruby.config") ret = subprocess.call(args, stdout=file(temp_config, "w")) if ret != 0: raise RuntimeError, "subprocess failed!" - return m5.objects.RubyMemory(config_file=temp_config, num_cpus=cores) + return m5.objects.RubyMemory(clock = ruby_tick, + config_file = temp_config, + num_cpus = cores, + range = AddrRange(str(memory_size)+"MB"), + num_dmas = dmas, + ports_per_core = ports_per_cpu) diff --git a/tests/configs/t1000-simple-atomic.py b/tests/configs/t1000-simple-atomic.py index 6a078e715..35b329f57 100644 --- a/tests/configs/t1000-simple-atomic.py +++ b/tests/configs/t1000-simple-atomic.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig cpu = AtomicSimpleCPU(cpu_id=0) diff --git a/tests/configs/tsunami-o3-dual.py b/tests/configs/tsunami-o3-dual.py index 3044f5433..76aca3806 100644 --- a/tests/configs/tsunami-o3-dual.py +++ b/tests/configs/tsunami-o3-dual.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig diff --git a/tests/configs/tsunami-o3.py b/tests/configs/tsunami-o3.py index 34fa235bd..9b52cd92b 100644 --- a/tests/configs/tsunami-o3.py +++ b/tests/configs/tsunami-o3.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig diff --git a/tests/configs/tsunami-simple-atomic-dual.py b/tests/configs/tsunami-simple-atomic-dual.py index 593b02680..dfbdd101d 100644 --- a/tests/configs/tsunami-simple-atomic-dual.py +++ b/tests/configs/tsunami-simple-atomic-dual.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig # -------------------- diff --git a/tests/configs/tsunami-simple-atomic.py b/tests/configs/tsunami-simple-atomic.py index 0c6feaeac..cfc619b06 100644 --- a/tests/configs/tsunami-simple-atomic.py +++ b/tests/configs/tsunami-simple-atomic.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig # -------------------- diff --git a/tests/configs/tsunami-simple-timing-dual.py b/tests/configs/tsunami-simple-timing-dual.py index 212449914..ce17475e3 100644 --- a/tests/configs/tsunami-simple-timing-dual.py +++ b/tests/configs/tsunami-simple-timing-dual.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig # -------------------- diff --git a/tests/configs/tsunami-simple-timing.py b/tests/configs/tsunami-simple-timing.py index f0eaa08d7..0c3984628 100644 --- a/tests/configs/tsunami-simple-timing.py +++ b/tests/configs/tsunami-simple-timing.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig diff --git a/tests/configs/twosys-tsunami-simple-atomic.py b/tests/configs/twosys-tsunami-simple-atomic.py index e7214a059..ce191930e 100644 --- a/tests/configs/twosys-tsunami-simple-atomic.py +++ b/tests/configs/twosys-tsunami-simple-atomic.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from FSConfig import * from Benchmarks import * diff --git a/tests/long/00.gzip/ref/x86/linux/simple-timing/config.ini b/tests/long/00.gzip/ref/x86/linux/simple-timing/config.ini index 033ea4c68..0c81e9129 100644 --- a/tests/long/00.gzip/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/00.gzip/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 diff --git a/tests/long/00.gzip/ref/x86/linux/simple-timing/simout b/tests/long/00.gzip/ref/x86/linux/simple-timing/simout index 7e3ef4fb7..8936a6094 100755 --- a/tests/long/00.gzip/ref/x86/linux/simple-timing/simout +++ b/tests/long/00.gzip/ref/x86/linux/simple-timing/simout @@ -5,10 +5,10 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 8 2009 12:09:45 -M5 revision f8cd1918b0c6 6483 default qtip tip condmovezerostats.patch -M5 started Aug 8 2009 12:09:46 -M5 executing on tater +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:32:22 +M5 executing on maize command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/00.gzip/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/00.gzip/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -44,4 +44,4 @@ Uncompressing Data Uncompressed data 1048576 bytes in length Uncompressed data compared correctly Tested 1MB buffer: OK! -Exiting @ tick 1814896735000 because target called exit() +Exiting @ tick 1814726932000 because target called exit() diff --git a/tests/long/00.gzip/ref/x86/linux/simple-timing/stats.txt b/tests/long/00.gzip/ref/x86/linux/simple-timing/stats.txt index 574e2f381..60806dc72 100644 --- a/tests/long/00.gzip/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/00.gzip/ref/x86/linux/simple-timing/stats.txt @@ -1,76 +1,76 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 989143 # Simulator instruction rate (inst/s) -host_mem_usage 205900 # Number of bytes of host memory used -host_seconds 1637.14 # Real time elapsed on the host -host_tick_rate 1108576660 # Simulator tick rate (ticks/s) +host_inst_rate 1181561 # Simulator instruction rate (inst/s) +host_mem_usage 194380 # Number of bytes of host memory used +host_seconds 1370.53 # Real time elapsed on the host +host_tick_rate 1324103876 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 1619366736 # Number of instructions simulated -sim_seconds 1.814897 # Number of seconds simulated -sim_ticks 1814896735000 # Number of ticks simulated +sim_seconds 1.814727 # Number of seconds simulated +sim_ticks 1814726932000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 419042118 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 20939.027041 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 17939.027041 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 418844309 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 4141928000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.000472 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 197809 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 3548501000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.000472 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 197809 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_avg_miss_latency 20884.820230 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 17884.820230 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 418844783 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 4121306000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.000471 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 197335 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 3529301000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.000471 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 197335 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 188186056 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 56000 # average WriteReq miss latency system.cpu.dcache.WriteReq_avg_mshr_miss_latency 53000 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 187873910 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 17480176000 # number of WriteReq miss cycles -system.cpu.dcache.WriteReq_miss_rate 0.001659 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 312146 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 16543738000 # number of WriteReq MSHR miss cycles -system.cpu.dcache.WriteReq_mshr_miss_rate 0.001659 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 312146 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_hits 187876631 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 17327800000 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.001644 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 309425 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 16399525000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.001644 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 309425 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 1364.014744 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 1372.614288 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 607228174 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 42400.023531 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 39400.023531 # average overall mshr miss latency -system.cpu.dcache.demand_hits 606718219 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 21622104000 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.000840 # miss rate for demand accesses -system.cpu.dcache.demand_misses 509955 # number of demand (read+write) misses +system.cpu.dcache.demand_avg_miss_latency 42325.964954 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 39325.964954 # average overall mshr miss latency +system.cpu.dcache.demand_hits 606721414 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 21449106000 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.000835 # miss rate for demand accesses +system.cpu.dcache.demand_misses 506760 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 20092239000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.000840 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 509955 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 19928826000 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.000835 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 506760 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 607228174 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 42400.023531 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 39400.023531 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 42325.964954 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 39325.964954 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 606718219 # number of overall hits -system.cpu.dcache.overall_miss_latency 21622104000 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.000840 # miss rate for overall accesses -system.cpu.dcache.overall_misses 509955 # number of overall misses +system.cpu.dcache.overall_hits 606721414 # number of overall hits +system.cpu.dcache.overall_miss_latency 21449106000 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.000835 # miss rate for overall accesses +system.cpu.dcache.overall_misses 506760 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 20092239000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.000840 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 509955 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 19928826000 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.000835 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 506760 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 440755 # number of replacements -system.cpu.dcache.sampled_refs 444851 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 437970 # number of replacements +system.cpu.dcache.sampled_refs 442066 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 4094.900211 # Cycle average of tags in use -system.cpu.dcache.total_refs 606783323 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 4094.901154 # Cycle average of tags in use +system.cpu.dcache.total_refs 606786108 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 779430000 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 308934 # number of writebacks +system.cpu.dcache.writebacks 306212 # number of writebacks system.cpu.icache.ReadReq_accesses 1186516703 # number of ReadReq accesses(hits+misses) system.cpu.icache.ReadReq_avg_miss_latency 56000 # average ReadReq miss latency system.cpu.icache.ReadReq_avg_mshr_miss_latency 53000 # average ReadReq mshr miss latency @@ -120,86 +120,86 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 4 # number of replacements system.cpu.icache.sampled_refs 722 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 660.162690 # Cycle average of tags in use +system.cpu.icache.tagsinuse 660.164909 # Cycle average of tags in use system.cpu.icache.total_refs 1186515981 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 247042 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_accesses 244731 # number of ReadExReq accesses(hits+misses) system.cpu.l2cache.ReadExReq_avg_miss_latency 52000 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 12846184000 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 12726012000 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 247042 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 9881680000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 244731 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 9789240000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 247042 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 198531 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_mshr_misses 244731 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 198057 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 165128 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 1736956000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.168251 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 33403 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 1336120000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.168251 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 33403 # number of ReadReq MSHR misses -system.cpu.l2cache.UpgradeReq_accesses 65104 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_hits 164987 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 1719640000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.166972 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 33070 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 1322800000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.166972 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 33070 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 64694 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 52000 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency -system.cpu.l2cache.UpgradeReq_miss_latency 3385408000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_latency 3364088000 # number of UpgradeReq miss cycles system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_misses 65104 # number of UpgradeReq misses -system.cpu.l2cache.UpgradeReq_mshr_miss_latency 2604160000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_misses 64694 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 2587760000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_mshr_misses 65104 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 308934 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 308934 # number of Writeback hits +system.cpu.l2cache.UpgradeReq_mshr_misses 64694 # number of UpgradeReq MSHR misses +system.cpu.l2cache.Writeback_accesses 306212 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 306212 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 3.437895 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 3.429569 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 445573 # number of demand (read+write) accesses +system.cpu.l2cache.demand_accesses 442788 # number of demand (read+write) accesses system.cpu.l2cache.demand_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 165128 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 14583140000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.629403 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 280445 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 164987 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 14445652000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.627391 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 277801 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 11217800000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.629403 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 280445 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 11112040000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.627391 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 277801 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 445573 # number of overall (read+write) accesses +system.cpu.l2cache.overall_accesses 442788 # number of overall (read+write) accesses system.cpu.l2cache.overall_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 165128 # number of overall hits -system.cpu.l2cache.overall_miss_latency 14583140000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.629403 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 280445 # number of overall misses +system.cpu.l2cache.overall_hits 164987 # number of overall hits +system.cpu.l2cache.overall_miss_latency 14445652000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.627391 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 277801 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 11217800000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.629403 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 280445 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 11112040000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.627391 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 277801 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.l2cache.replacements 82239 # number of replacements -system.cpu.l2cache.sampled_refs 97729 # Sample count of references to valid blocks. +system.cpu.l2cache.replacements 81543 # number of replacements +system.cpu.l2cache.sampled_refs 97060 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 16489.401861 # Cycle average of tags in use -system.cpu.l2cache.total_refs 335982 # Total number of references to valid blocks. +system.cpu.l2cache.tagsinuse 16545.401704 # Cycle average of tags in use +system.cpu.l2cache.total_refs 332874 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. -system.cpu.l2cache.writebacks 61724 # number of writebacks +system.cpu.l2cache.writebacks 61555 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 3629793470 # number of cpu cycles simulated +system.cpu.numCycles 3629453864 # number of cpu cycles simulated system.cpu.num_insts 1619366736 # Number of instructions executed system.cpu.num_refs 607228174 # Number of memory references system.cpu.workload.PROG:num_syscalls 48 # Number of system calls diff --git a/tests/long/00.gzip/test.py b/tests/long/00.gzip/test.py index f69914046..7acce6e81 100644 --- a/tests/long/00.gzip/test.py +++ b/tests/long/00.gzip/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import gzip_log workload = gzip_log(isa, opsys, 'smred') diff --git a/tests/long/10.mcf/ref/x86/linux/simple-timing/config.ini b/tests/long/10.mcf/ref/x86/linux/simple-timing/config.ini index 40547fe1c..c90ba3ccf 100644 --- a/tests/long/10.mcf/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/10.mcf/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 @@ -152,7 +149,7 @@ type=ExeTracer [system.cpu.workload] type=LiveProcess cmd=mcf mcf.in -cwd=build/X86_SE/tests/opt/long/10.mcf/x86/linux/simple-timing +cwd=build/X86_SE/tests/fast/long/10.mcf/x86/linux/simple-timing egid=100 env= errout=cerr diff --git a/tests/long/10.mcf/ref/x86/linux/simple-timing/simout b/tests/long/10.mcf/ref/x86/linux/simple-timing/simout index 2a93c45ae..035c663f2 100755 --- a/tests/long/10.mcf/ref/x86/linux/simple-timing/simout +++ b/tests/long/10.mcf/ref/x86/linux/simple-timing/simout @@ -5,11 +5,11 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 17 2009 20:29:57 -M5 revision 84f7bdc43a4f 6605 default qtip tip x86fsdate.patch -M5 started Aug 17 2009 20:30:53 -M5 executing on tater -command line: build/X86_SE/m5.opt -d build/X86_SE/tests/opt/long/10.mcf/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/opt/long/10.mcf/x86/linux/simple-timing +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:34:05 +M5 executing on maize +command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/10.mcf/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/10.mcf/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -28,4 +28,4 @@ simplex iterations : 2663 flow value : 3080014995 checksum : 68389 optimal -Exiting @ tick 381620562000 because target called exit() +Exiting @ tick 382091472000 because target called exit() diff --git a/tests/long/10.mcf/ref/x86/linux/simple-timing/stats.txt b/tests/long/10.mcf/ref/x86/linux/simple-timing/stats.txt index a882827d5..b582ff405 100644 --- a/tests/long/10.mcf/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/10.mcf/ref/x86/linux/simple-timing/stats.txt @@ -1,76 +1,76 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 395133 # Simulator instruction rate (inst/s) -host_mem_usage 355296 # Number of bytes of host memory used -host_seconds 682.55 # Real time elapsed on the host -host_tick_rate 559113861 # Simulator tick rate (ticks/s) +host_inst_rate 839358 # Simulator instruction rate (inst/s) +host_mem_usage 328912 # Number of bytes of host memory used +host_seconds 321.31 # Real time elapsed on the host +host_tick_rate 1189158712 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 269695959 # Number of instructions simulated -sim_seconds 0.381621 # Number of seconds simulated -sim_ticks 381620562000 # Number of ticks simulated +sim_seconds 0.382091 # Number of seconds simulated +sim_ticks 382091472000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 90779443 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 15899.099984 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 12899.099984 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 88829255 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 31006234000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.021483 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 1950188 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 25155670000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.021483 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 1950188 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_avg_miss_latency 15892.729148 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 12892.729148 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 88818985 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 31157028000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.021596 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 1960458 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 25275654000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.021596 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 1960458 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 31439750 # number of WriteReq accesses(hits+misses) -system.cpu.dcache.WriteReq_avg_miss_latency 56000.034908 # average WriteReq miss latency -system.cpu.dcache.WriteReq_avg_mshr_miss_latency 53000.034908 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 31210573 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 12833920000 # number of WriteReq miss cycles -system.cpu.dcache.WriteReq_miss_rate 0.007289 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 229177 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 12146389000 # number of WriteReq MSHR miss cycles -system.cpu.dcache.WriteReq_mshr_miss_rate 0.007289 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 229177 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_avg_miss_latency 56000.038268 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 53000.038268 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 31204566 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 13170313000 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.007480 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 235184 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 12464761000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.007480 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 235184 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 58.501856 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 58.134189 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 122219193 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 20116.021869 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 17116.021869 # average overall mshr miss latency -system.cpu.dcache.demand_hits 120039828 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 43840154000 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.017832 # miss rate for demand accesses -system.cpu.dcache.demand_misses 2179365 # number of demand (read+write) misses +system.cpu.dcache.demand_avg_miss_latency 20188.783508 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 17188.783508 # average overall mshr miss latency +system.cpu.dcache.demand_hits 120023551 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 44327341000 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.017965 # miss rate for demand accesses +system.cpu.dcache.demand_misses 2195642 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 37302059000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.017832 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 2179365 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 37740415000 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.017965 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 2195642 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 122219193 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 20116.021869 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 17116.021869 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 20188.783508 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 17188.783508 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 120039828 # number of overall hits -system.cpu.dcache.overall_miss_latency 43840154000 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.017832 # miss rate for overall accesses -system.cpu.dcache.overall_misses 2179365 # number of overall misses +system.cpu.dcache.overall_hits 120023551 # number of overall hits +system.cpu.dcache.overall_miss_latency 44327341000 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.017965 # miss rate for overall accesses +system.cpu.dcache.overall_misses 2195642 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 37302059000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.017832 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 2179365 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 37740415000 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.017965 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 2195642 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 2049944 # number of replacements -system.cpu.dcache.sampled_refs 2054040 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 2062715 # number of replacements +system.cpu.dcache.sampled_refs 2066811 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 4079.426853 # Cycle average of tags in use -system.cpu.dcache.total_refs 120165153 # Total number of references to valid blocks. -system.cpu.dcache.warmup_cycle 127225673000 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 229129 # number of writebacks +system.cpu.dcache.tagsinuse 4077.137530 # Cycle average of tags in use +system.cpu.dcache.total_refs 120152382 # Total number of references to valid blocks. +system.cpu.dcache.warmup_cycle 127457925000 # Cycle when the warmup percentage was hit. +system.cpu.dcache.writebacks 235136 # number of writebacks system.cpu.icache.ReadReq_accesses 217696172 # number of ReadReq accesses(hits+misses) system.cpu.icache.ReadReq_avg_miss_latency 56000 # average ReadReq miss latency system.cpu.icache.ReadReq_avg_mshr_miss_latency 53000 # average ReadReq mshr miss latency @@ -120,86 +120,86 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 24 # number of replacements system.cpu.icache.sampled_refs 808 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 667.511289 # Cycle average of tags in use +system.cpu.icache.tagsinuse 667.480800 # Cycle average of tags in use system.cpu.icache.total_refs 217695364 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 103852 # number of ReadExReq accesses(hits+misses) -system.cpu.l2cache.ReadExReq_avg_miss_latency 52000.298502 # average ReadExReq miss latency +system.cpu.l2cache.ReadExReq_accesses 106353 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_avg_miss_latency 52000.291482 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 5400335000 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 5530387000 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 103852 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 4154080000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 106353 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 4254120000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 103852 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 1950996 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_mshr_misses 106353 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 1961266 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 1862007 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 4627428000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.045612 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 88989 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 3559560000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.045612 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 88989 # number of ReadReq MSHR misses -system.cpu.l2cache.UpgradeReq_accesses 125325 # number of UpgradeReq accesses(hits+misses) -system.cpu.l2cache.UpgradeReq_avg_miss_latency 51990.456812 # average UpgradeReq miss latency +system.cpu.l2cache.ReadReq_hits 1872110 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 4636112000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.045458 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 89156 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 3566240000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.045458 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 89156 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 128831 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.UpgradeReq_avg_miss_latency 51991.120150 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency -system.cpu.l2cache.UpgradeReq_miss_latency 6515704000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_latency 6698068000 # number of UpgradeReq miss cycles system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_misses 125325 # number of UpgradeReq misses -system.cpu.l2cache.UpgradeReq_mshr_miss_latency 5013000000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_misses 128831 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 5153240000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_mshr_misses 125325 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 229129 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 229129 # number of Writeback hits +system.cpu.l2cache.UpgradeReq_mshr_misses 128831 # number of UpgradeReq MSHR misses +system.cpu.l2cache.Writeback_accesses 235136 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 235136 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 13.678118 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 13.775269 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 2054848 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 52000.160754 # average overall miss latency +system.cpu.l2cache.demand_accesses 2067619 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 52000.158560 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 1862007 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 10027763000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.093847 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 192841 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 1872110 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 10166499000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.094558 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 195509 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 7713640000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.093847 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 192841 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 7820360000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.094558 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 195509 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 2054848 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 52000.160754 # average overall miss latency +system.cpu.l2cache.overall_accesses 2067619 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 52000.158560 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 1862007 # number of overall hits -system.cpu.l2cache.overall_miss_latency 10027763000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.093847 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 192841 # number of overall misses +system.cpu.l2cache.overall_hits 1872110 # number of overall hits +system.cpu.l2cache.overall_miss_latency 10166499000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.094558 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 195509 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 7713640000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.093847 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 192841 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 7820360000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.094558 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 195509 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.l2cache.replacements 108886 # number of replacements -system.cpu.l2cache.sampled_refs 132828 # Sample count of references to valid blocks. +system.cpu.l2cache.replacements 109056 # number of replacements +system.cpu.l2cache.sampled_refs 132990 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 18003.313178 # Cycle average of tags in use -system.cpu.l2cache.total_refs 1816837 # Total number of references to valid blocks. +system.cpu.l2cache.tagsinuse 18001.651383 # Cycle average of tags in use +system.cpu.l2cache.total_refs 1831973 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. -system.cpu.l2cache.writebacks 70892 # number of writebacks +system.cpu.l2cache.writebacks 70891 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 763241124 # number of cpu cycles simulated +system.cpu.numCycles 764182944 # number of cpu cycles simulated system.cpu.num_insts 269695959 # Number of instructions executed system.cpu.num_refs 122219131 # Number of memory references system.cpu.workload.PROG:num_syscalls 444 # Number of system calls diff --git a/tests/long/10.mcf/test.py b/tests/long/10.mcf/test.py index c4ffb248a..9bd18a83f 100644 --- a/tests/long/10.mcf/test.py +++ b/tests/long/10.mcf/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import mcf workload = mcf(isa, opsys, 'smred') diff --git a/tests/long/20.parser/ref/x86/linux/simple-timing/config.ini b/tests/long/20.parser/ref/x86/linux/simple-timing/config.ini index 5f5b1b01c..a7ed66f8a 100644 --- a/tests/long/20.parser/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/20.parser/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 diff --git a/tests/long/20.parser/ref/x86/linux/simple-timing/simout b/tests/long/20.parser/ref/x86/linux/simple-timing/simout index a5dbe2b41..a11db4e1e 100755 --- a/tests/long/20.parser/ref/x86/linux/simple-timing/simout +++ b/tests/long/20.parser/ref/x86/linux/simple-timing/simout @@ -5,10 +5,10 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 8 2009 12:09:45 -M5 revision f8cd1918b0c6 6483 default qtip tip condmovezerostats.patch -M5 started Aug 8 2009 12:09:46 -M5 executing on tater +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:39:28 +M5 executing on maize command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/20.parser/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/20.parser/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -74,4 +74,4 @@ info: Increasing stack size by one page. about 2 million people attended the five best costumes got prizes No errors! -Exiting @ tick 1722352562000 because target called exit() +Exiting @ tick 1722331568000 because target called exit() diff --git a/tests/long/20.parser/ref/x86/linux/simple-timing/stats.txt b/tests/long/20.parser/ref/x86/linux/simple-timing/stats.txt index c62dd0754..0e665b6ef 100644 --- a/tests/long/20.parser/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/20.parser/ref/x86/linux/simple-timing/stats.txt @@ -1,84 +1,84 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 924480 # Simulator instruction rate (inst/s) -host_mem_usage 209588 # Number of bytes of host memory used -host_seconds 1617.88 # Real time elapsed on the host -host_tick_rate 1064572030 # Simulator tick rate (ticks/s) +host_inst_rate 1459378 # Simulator instruction rate (inst/s) +host_mem_usage 198104 # Number of bytes of host memory used +host_seconds 1024.89 # Real time elapsed on the host +host_tick_rate 1680505604 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 1495700470 # Number of instructions simulated -sim_seconds 1.722353 # Number of seconds simulated -sim_ticks 1722352562000 # Number of ticks simulated +sim_seconds 1.722332 # Number of seconds simulated +sim_ticks 1722331568000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 384102182 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 24147.662775 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 21147.661617 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 382375369 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 41698498000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.004496 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 1726813 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 36518057000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.004496 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 1726813 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_avg_miss_latency 24153.691272 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 21153.690114 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 382374810 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 41722410000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.004497 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 1727372 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 36540292000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.004497 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 1727372 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 149160200 # number of WriteReq accesses(hits+misses) -system.cpu.dcache.WriteReq_avg_miss_latency 55999.912355 # average WriteReq miss latency -system.cpu.dcache.WriteReq_avg_mshr_miss_latency 52999.912355 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 147694052 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 82104159500 # number of WriteReq miss cycles -system.cpu.dcache.WriteReq_miss_rate 0.009829 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 1466148 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 77705715500 # number of WriteReq MSHR miss cycles -system.cpu.dcache.WriteReq_mshr_miss_rate 0.009829 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 1466148 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_avg_miss_latency 55999.912307 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 52999.912307 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 147694869 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 82058407500 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.009824 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 1465331 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 77662414500 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.009824 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 1465331 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 210.782575 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 210.745406 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 533262382 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 38773.620317 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 35773.619690 # average overall mshr miss latency -system.cpu.dcache.demand_hits 530069421 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 123802657500 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.005988 # miss rate for demand accesses -system.cpu.dcache.demand_misses 3192961 # number of demand (read+write) misses +system.cpu.dcache.demand_avg_miss_latency 38769.912986 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 35769.912360 # average overall mshr miss latency +system.cpu.dcache.demand_hits 530069679 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 123780817500 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.005987 # miss rate for demand accesses +system.cpu.dcache.demand_misses 3192703 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 114223772500 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.005988 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 3192961 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 114202706500 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.005987 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 3192703 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 533262382 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 38773.620317 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 35773.619690 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 38769.912986 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 35769.912360 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 530069421 # number of overall hits -system.cpu.dcache.overall_miss_latency 123802657500 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.005988 # miss rate for overall accesses -system.cpu.dcache.overall_misses 3192961 # number of overall misses +system.cpu.dcache.overall_hits 530069679 # number of overall hits +system.cpu.dcache.overall_miss_latency 123780817500 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.005987 # miss rate for overall accesses +system.cpu.dcache.overall_misses 3192703 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 114223772500 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.005988 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 3192961 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 114202706500 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.005987 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 3192703 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 2513875 # number of replacements -system.cpu.dcache.sampled_refs 2517971 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 2514317 # number of replacements +system.cpu.dcache.sampled_refs 2518413 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 4086.831173 # Cycle average of tags in use -system.cpu.dcache.total_refs 530744411 # Total number of references to valid blocks. -system.cpu.dcache.warmup_cycle 8217762000 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 1463913 # number of writebacks +system.cpu.dcache.tagsinuse 4086.814341 # Cycle average of tags in use +system.cpu.dcache.total_refs 530743969 # Total number of references to valid blocks. +system.cpu.dcache.warmup_cycle 8217895000 # Cycle when the warmup percentage was hit. +system.cpu.dcache.writebacks 1463113 # number of writebacks system.cpu.icache.ReadReq_accesses 1068347073 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 48417.910448 # average ReadReq miss latency -system.cpu.icache.ReadReq_avg_mshr_miss_latency 45417.910448 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_avg_miss_latency 48626.865672 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 45626.865672 # average ReadReq mshr miss latency system.cpu.icache.ReadReq_hits 1068344259 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 136248000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_latency 136836000 # number of ReadReq miss cycles system.cpu.icache.ReadReq_miss_rate 0.000003 # miss rate for ReadReq accesses system.cpu.icache.ReadReq_misses 2814 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_miss_latency 127806000 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_latency 128394000 # number of ReadReq MSHR miss cycles system.cpu.icache.ReadReq_mshr_miss_rate 0.000003 # mshr miss rate for ReadReq accesses system.cpu.icache.ReadReq_mshr_misses 2814 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked @@ -90,29 +90,29 @@ system.cpu.icache.blocked_cycles::no_mshrs 0 # system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed system.cpu.icache.demand_accesses 1068347073 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 48417.910448 # average overall miss latency -system.cpu.icache.demand_avg_mshr_miss_latency 45417.910448 # average overall mshr miss latency +system.cpu.icache.demand_avg_miss_latency 48626.865672 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 45626.865672 # average overall mshr miss latency system.cpu.icache.demand_hits 1068344259 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 136248000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_latency 136836000 # number of demand (read+write) miss cycles system.cpu.icache.demand_miss_rate 0.000003 # miss rate for demand accesses system.cpu.icache.demand_misses 2814 # number of demand (read+write) misses system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.icache.demand_mshr_miss_latency 127806000 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_latency 128394000 # number of demand (read+write) MSHR miss cycles system.cpu.icache.demand_mshr_miss_rate 0.000003 # mshr miss rate for demand accesses system.cpu.icache.demand_mshr_misses 2814 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.icache.overall_accesses 1068347073 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 48417.910448 # average overall miss latency -system.cpu.icache.overall_avg_mshr_miss_latency 45417.910448 # average overall mshr miss latency +system.cpu.icache.overall_avg_miss_latency 48626.865672 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 45626.865672 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.icache.overall_hits 1068344259 # number of overall hits -system.cpu.icache.overall_miss_latency 136248000 # number of overall miss cycles +system.cpu.icache.overall_miss_latency 136836000 # number of overall miss cycles system.cpu.icache.overall_miss_rate 0.000003 # miss rate for overall accesses system.cpu.icache.overall_misses 2814 # number of overall misses system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.icache.overall_mshr_miss_latency 127806000 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_latency 128394000 # number of overall MSHR miss cycles system.cpu.icache.overall_mshr_miss_rate 0.000003 # mshr miss rate for overall accesses system.cpu.icache.overall_mshr_misses 2814 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles @@ -120,86 +120,86 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 1253 # number of replacements system.cpu.icache.sampled_refs 2814 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 887.487990 # Cycle average of tags in use +system.cpu.icache.tagsinuse 887.538461 # Cycle average of tags in use system.cpu.icache.total_refs 1068344259 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 791158 # number of ReadExReq accesses(hits+misses) -system.cpu.l2cache.ReadExReq_avg_miss_latency 52000.014536 # average ReadExReq miss latency +system.cpu.l2cache.ReadExReq_accesses 791041 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_avg_miss_latency 52000.014538 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 41140227500 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 41134143500 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 791158 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 31646320000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 791041 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 31641640000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 791158 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 1729627 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_mshr_misses 791041 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 1730186 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 1310104 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 21815196000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.242551 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 419523 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 16780920000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.242551 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 419523 # number of ReadReq MSHR misses -system.cpu.l2cache.UpgradeReq_accesses 674990 # number of UpgradeReq accesses(hits+misses) -system.cpu.l2cache.UpgradeReq_avg_miss_latency 51989.214655 # average UpgradeReq miss latency +system.cpu.l2cache.ReadReq_hits 1310266 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 21835840000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.242702 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 419920 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 16796800000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.242702 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 419920 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 674290 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.UpgradeReq_avg_miss_latency 51989.203458 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency -system.cpu.l2cache.UpgradeReq_miss_latency 35092200000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_latency 35055800000 # number of UpgradeReq miss cycles system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_misses 674990 # number of UpgradeReq misses -system.cpu.l2cache.UpgradeReq_mshr_miss_latency 26999600000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_misses 674290 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 26971600000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_mshr_misses 674990 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 1463913 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 1463913 # number of Writeback hits +system.cpu.l2cache.UpgradeReq_mshr_misses 674290 # number of UpgradeReq MSHR misses +system.cpu.l2cache.Writeback_accesses 1463113 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 1463113 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 3.428066 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 3.423900 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 2520785 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 52000.009499 # average overall miss latency +system.cpu.l2cache.demand_accesses 2521227 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 52000.009497 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 1310104 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 62955423500 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.480279 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 1210681 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 1310266 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 62969983500 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.480306 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 1210961 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 48427240000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.480279 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 1210681 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 48438440000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.480306 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 1210961 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 2520785 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 52000.009499 # average overall miss latency +system.cpu.l2cache.overall_accesses 2521227 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 52000.009497 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 1310104 # number of overall hits -system.cpu.l2cache.overall_miss_latency 62955423500 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.480279 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 1210681 # number of overall misses +system.cpu.l2cache.overall_hits 1310266 # number of overall hits +system.cpu.l2cache.overall_miss_latency 62969983500 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.480306 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 1210961 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 48427240000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.480279 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 1210681 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 48438440000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.480306 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 1210961 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.l2cache.replacements 663513 # number of replacements -system.cpu.l2cache.sampled_refs 679921 # Sample count of references to valid blocks. +system.cpu.l2cache.replacements 664073 # number of replacements +system.cpu.l2cache.sampled_refs 680479 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 17216.037197 # Cycle average of tags in use -system.cpu.l2cache.total_refs 2330814 # Total number of references to valid blocks. -system.cpu.l2cache.warmup_cycle 921771494000 # Cycle when the warmup percentage was hit. -system.cpu.l2cache.writebacks 481430 # number of writebacks +system.cpu.l2cache.tagsinuse 17213.177564 # Cycle average of tags in use +system.cpu.l2cache.total_refs 2329892 # Total number of references to valid blocks. +system.cpu.l2cache.warmup_cycle 921652677000 # Cycle when the warmup percentage was hit. +system.cpu.l2cache.writebacks 481653 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 3444705124 # number of cpu cycles simulated +system.cpu.numCycles 3444663136 # number of cpu cycles simulated system.cpu.num_insts 1495700470 # Number of instructions executed system.cpu.num_refs 533262337 # Number of memory references system.cpu.workload.PROG:num_syscalls 551 # Number of system calls diff --git a/tests/long/20.parser/test.py b/tests/long/20.parser/test.py index 8e745ec26..c96a46e60 100644 --- a/tests/long/20.parser/test.py +++ b/tests/long/20.parser/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import parser workload = parser(isa, opsys, 'mdred') diff --git a/tests/long/30.eon/test.py b/tests/long/30.eon/test.py index 318da1049..de4d12dd8 100644 --- a/tests/long/30.eon/test.py +++ b/tests/long/30.eon/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import eon_cook workload = eon_cook(isa, opsys, 'mdred') diff --git a/tests/long/40.perlbmk/test.py b/tests/long/40.perlbmk/test.py index e32416265..8fe5d6047 100644 --- a/tests/long/40.perlbmk/test.py +++ b/tests/long/40.perlbmk/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import perlbmk_makerand workload = perlbmk_makerand(isa, opsys, 'lgred') diff --git a/tests/long/50.vortex/test.py b/tests/long/50.vortex/test.py index fbf0dc081..92422c234 100644 --- a/tests/long/50.vortex/test.py +++ b/tests/long/50.vortex/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import vortex workload = vortex(isa, opsys, 'smred') diff --git a/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simout b/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simout index 84bba46f1..26e42fa14 100755 --- a/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simout +++ b/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simout @@ -5,9 +5,9 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Jul 6 2009 11:03:45 -M5 revision d3635cac686a 6289 default ruby_refs.diff qtip tip -M5 started Jul 6 2009 11:56:32 +M5 compiled Oct 22 2009 13:11:07 +M5 revision e406bb83c56f 6682 default qtip tip syscall-ioctl.patch +M5 started Oct 22 2009 13:42:59 M5 executing on maize command line: build/ALPHA_SE/m5.fast -d build/ALPHA_SE/tests/fast/long/60.bzip2/alpha/tru64/o3-timing -re tests/run.py build/ALPHA_SE/tests/fast/long/60.bzip2/alpha/tru64/o3-timing Global frequency set at 1000000000000 ticks per second diff --git a/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stats.txt b/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stats.txt index 3a8e7864a..d858d0b22 100644 --- a/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stats.txt +++ b/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stats.txt @@ -1,9 +1,9 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 222565 # Simulator instruction rate (inst/s) -host_mem_usage 190364 # Number of bytes of host memory used -host_seconds 7800.15 # Real time elapsed on the host -host_tick_rate 95165996 # Simulator tick rate (ticks/s) +host_inst_rate 254978 # Simulator instruction rate (inst/s) +host_mem_usage 190768 # Number of bytes of host memory used +host_seconds 6808.60 # Real time elapsed on the host +host_tick_rate 109025257 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 1736043781 # Number of instructions simulated sim_seconds 0.742309 # Number of seconds simulated @@ -133,17 +133,17 @@ system.cpu.decode.DECODE:RunCycles 549143104 # Nu system.cpu.decode.DECODE:SquashCycles 93084202 # Number of cycles decode is squashing system.cpu.decode.DECODE:SquashedInsts 1641 # Number of squashed instructions handled by decode system.cpu.decode.DECODE:UnblockCycles 5133136 # Number of cycles decode is unblocking -system.cpu.dtb.data_accesses 768331639 # DTB accesses +system.cpu.dtb.data_accesses 768331641 # DTB accesses system.cpu.dtb.data_acv 0 # DTB access violations -system.cpu.dtb.data_hits 752318838 # DTB hits +system.cpu.dtb.data_hits 752318840 # DTB hits system.cpu.dtb.data_misses 16012801 # DTB misses system.cpu.dtb.fetch_accesses 0 # ITB accesses system.cpu.dtb.fetch_acv 0 # ITB acv system.cpu.dtb.fetch_hits 0 # ITB hits system.cpu.dtb.fetch_misses 0 # ITB misses -system.cpu.dtb.read_accesses 566617551 # DTB read accesses +system.cpu.dtb.read_accesses 566617553 # DTB read accesses system.cpu.dtb.read_acv 0 # DTB read access violations -system.cpu.dtb.read_hits 557381525 # DTB read hits +system.cpu.dtb.read_hits 557381527 # DTB read hits system.cpu.dtb.read_misses 9236026 # DTB read misses system.cpu.dtb.write_accesses 201714088 # DTB write accesses system.cpu.dtb.write_acv 0 # DTB write access violations @@ -234,17 +234,17 @@ system.cpu.idleCycles 12319311 # To system.cpu.iew.EXEC:branches 282186314 # Number of branches executed system.cpu.iew.EXEC:nop 128796557 # number of nop insts executed system.cpu.iew.EXEC:rate 1.535065 # Inst execution rate -system.cpu.iew.EXEC:refs 769619324 # number of memory reference insts executed +system.cpu.iew.EXEC:refs 769619326 # number of memory reference insts executed system.cpu.iew.EXEC:stores 201925301 # Number of stores executed system.cpu.iew.EXEC:swp 0 # number of swp insts executed -system.cpu.iew.WB:consumers 1531990762 # num instructions consuming a value -system.cpu.iew.WB:count 2240290242 # cumulative count of insts written-back +system.cpu.iew.WB:consumers 1531990764 # num instructions consuming a value +system.cpu.iew.WB:count 2240290245 # cumulative count of insts written-back system.cpu.iew.WB:fanout 0.811831 # average fanout of values written-back system.cpu.iew.WB:penalized 0 # number of instrctions required to write to 'other' IQ system.cpu.iew.WB:penalized_rate 0 # fraction of instructions written-back that wrote to 'other' IQ -system.cpu.iew.WB:producers 1243717865 # num instructions producing a value +system.cpu.iew.WB:producers 1243717866 # num instructions producing a value system.cpu.iew.WB:rate 1.509000 # insts written-back per cycle -system.cpu.iew.WB:sent 2261678939 # cumulative count of insts sent to commit +system.cpu.iew.WB:sent 2261678943 # cumulative count of insts sent to commit system.cpu.iew.branchMispredicts 21342134 # Number of branch mispredicts detected at execute system.cpu.iew.iewBlockCycles 17373691 # Number of cycles IEW is blocking system.cpu.iew.iewDispLoadInsts 621608435 # Number of dispatched load instructions @@ -252,9 +252,9 @@ system.cpu.iew.iewDispNonSpecInsts 43 # Nu system.cpu.iew.iewDispSquashedInsts 22154841 # Number of squashed instructions skipped by dispatch system.cpu.iew.iewDispStoreInsts 234046222 # Number of dispatched store instructions system.cpu.iew.iewDispatchedInsts 2621719109 # Number of instructions dispatched to IQ -system.cpu.iew.iewExecLoadInsts 567694023 # Number of load instructions executed -system.cpu.iew.iewExecSquashedInsts 36858073 # Number of squashed instructions skipped in execute -system.cpu.iew.iewExecutedInsts 2278986827 # Number of executed instructions +system.cpu.iew.iewExecLoadInsts 567694025 # Number of load instructions executed +system.cpu.iew.iewExecSquashedInsts 36858071 # Number of squashed instructions skipped in execute +system.cpu.iew.iewExecutedInsts 2278986831 # Number of executed instructions system.cpu.iew.iewIQFullEvents 339653 # Number of times the IQ has become full, causing a stall system.cpu.iew.iewIdleCycles 0 # Number of cycles IEW is idle system.cpu.iew.iewLSQFullEvents 40208 # Number of times the LSQ has become full, causing a stall @@ -262,7 +262,7 @@ system.cpu.iew.iewSquashCycles 93084202 # Nu system.cpu.iew.iewUnblockCycles 758573 # Number of cycles IEW is unblocking system.cpu.iew.lsq.thread.0.blockedLoads 0 # Number of blocked loads due to partial load-store forwarding system.cpu.iew.lsq.thread.0.cacheBlocked 361643 # Number of times an access to memory failed due to the cache being blocked -system.cpu.iew.lsq.thread.0.forwLoads 33889596 # Number of loads that had data forwarded from stores +system.cpu.iew.lsq.thread.0.forwLoads 33889598 # Number of loads that had data forwarded from stores system.cpu.iew.lsq.thread.0.ignoredResponses 220185 # Number of memory responses ignored because the instruction is squashed system.cpu.iew.lsq.thread.0.invAddrLoads 0 # Number of loads ignored due to an invalid address system.cpu.iew.lsq.thread.0.invAddrSwpfs 0 # Number of software prefetches ignored due to an invalid address @@ -276,7 +276,7 @@ system.cpu.iew.predictedTakenIncorrect 20638338 # Nu system.cpu.ipc 1.169353 # IPC: Instructions Per Cycle system.cpu.ipc_total 1.169353 # IPC: Total IPC of All Threads system.cpu.iq.ISSUE:FU_type_0::No_OpClass 0 0.00% 0.00% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::IntAlu 1532920254 66.19% 66.19% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntAlu 1532920256 66.19% 66.19% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::IntMult 99 0.00% 66.19% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::IntDiv 0 0.00% 66.19% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::FloatAdd 234 0.00% 66.19% # Type of FU issued @@ -289,7 +289,7 @@ system.cpu.iq.ISSUE:FU_type_0::MemRead 577889733 24.95% 91.15% # Ty system.cpu.iq.ISSUE:FU_type_0::MemWrite 205034377 8.85% 100.00% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::IprAccess 0 0.00% 100.00% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::InstPrefetch 0 0.00% 100.00% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::total 2315844900 # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::total 2315844902 # Type of FU issued system.cpu.iq.ISSUE:fu_busy_cnt 14393569 # FU busy when requested system.cpu.iq.ISSUE:fu_busy_rate 0.006215 # FU busy rate (busy events/executed inst) system.cpu.iq.ISSUE:fu_full::No_OpClass 0 0.00% 0.00% # attempts to use FU when none available @@ -311,9 +311,9 @@ system.cpu.iq.ISSUE:issued_per_cycle::mean 1.572944 # system.cpu.iq.ISSUE:issued_per_cycle::stdev 1.737325 # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::underflows 0 0.00% 0.00% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::0-1 577695763 39.24% 39.24% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::1-2 271543756 18.44% 57.68% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::1-2 271543755 18.44% 57.68% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::2-3 242868170 16.50% 74.18% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::3-4 139713874 9.49% 83.67% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::3-4 139713875 9.49% 83.67% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::4-5 122021082 8.29% 91.95% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::5-6 69652698 4.73% 96.69% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::6-7 39670196 2.69% 99.38% # Number of insts issued each cycle @@ -325,12 +325,12 @@ system.cpu.iq.ISSUE:issued_per_cycle::max_value 8 system.cpu.iq.ISSUE:issued_per_cycle::total 1472299541 # Number of insts issued each cycle system.cpu.iq.ISSUE:rate 1.559892 # Inst issue rate system.cpu.iq.iqInstsAdded 2492922509 # Number of instructions added to the IQ (excludes non-spec) -system.cpu.iq.iqInstsIssued 2315844900 # Number of instructions issued +system.cpu.iq.iqInstsIssued 2315844902 # Number of instructions issued system.cpu.iq.iqNonSpecInstsAdded 43 # Number of non-speculative instructions added to the IQ system.cpu.iq.iqSquashedInstsExamined 739697610 # Number of squashed instructions iterated over during squash; mainly for profiling system.cpu.iq.iqSquashedInstsIssued 1501741 # Number of squashed instructions issued system.cpu.iq.iqSquashedNonSpecRemoved 14 # Number of squashed non-spec instructions that were removed -system.cpu.iq.iqSquashedOperandsExamined 329349456 # Number of squashed operands that are examined and possibly removed from graph +system.cpu.iq.iqSquashedOperandsExamined 329349452 # Number of squashed operands that are examined and possibly removed from graph system.cpu.itb.data_accesses 0 # DTB accesses system.cpu.itb.data_acv 0 # DTB access violations system.cpu.itb.data_hits 0 # DTB hits diff --git a/tests/long/60.bzip2/ref/x86/linux/simple-timing/config.ini b/tests/long/60.bzip2/ref/x86/linux/simple-timing/config.ini index 2985d5b21..d5c949c6e 100644 --- a/tests/long/60.bzip2/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/60.bzip2/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 diff --git a/tests/long/60.bzip2/ref/x86/linux/simple-timing/simout b/tests/long/60.bzip2/ref/x86/linux/simple-timing/simout index ea6185a03..8e0139bb7 100755 --- a/tests/long/60.bzip2/ref/x86/linux/simple-timing/simout +++ b/tests/long/60.bzip2/ref/x86/linux/simple-timing/simout @@ -5,10 +5,10 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 8 2009 12:09:45 -M5 revision f8cd1918b0c6 6483 default qtip tip condmovezerostats.patch -M5 started Aug 8 2009 12:13:11 -M5 executing on tater +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:30:56 +M5 executing on maize command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/60.bzip2/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/60.bzip2/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -29,4 +29,4 @@ Uncompressing Data Uncompressed data 1048576 bytes in length Uncompressed data compared correctly Tested 1MB buffer: OK! -Exiting @ tick 5988064038000 because target called exit() +Exiting @ tick 5988037845000 because target called exit() diff --git a/tests/long/60.bzip2/ref/x86/linux/simple-timing/stats.txt b/tests/long/60.bzip2/ref/x86/linux/simple-timing/stats.txt index 129e4b866..ffd34c1e6 100644 --- a/tests/long/60.bzip2/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/60.bzip2/ref/x86/linux/simple-timing/stats.txt @@ -1,76 +1,76 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 1178978 # Simulator instruction rate (inst/s) -host_mem_usage 205796 # Number of bytes of host memory used -host_seconds 3946.92 # Real time elapsed on the host -host_tick_rate 1517149915 # Simulator tick rate (ticks/s) +host_inst_rate 1485872 # Simulator instruction rate (inst/s) +host_mem_usage 194272 # Number of bytes of host memory used +host_seconds 3131.72 # Real time elapsed on the host +host_tick_rate 1912063349 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 4653327894 # Number of instructions simulated -sim_seconds 5.988064 # Number of seconds simulated -sim_ticks 5988064038000 # Number of ticks simulated +sim_seconds 5.988038 # Number of seconds simulated +sim_ticks 5988037845000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 1239184742 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 25017.713978 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 22017.713978 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 1231961294 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 180714156000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.005829 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 7223448 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 159043812000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.005829 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 7223448 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_avg_miss_latency 25018.463901 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 22018.463901 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 1231962487 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 180689726000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.005828 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 7222255 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 159022961000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.005828 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 7222255 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 438528336 # number of WriteReq accesses(hits+misses) -system.cpu.dcache.WriteReq_avg_miss_latency 55999.834453 # average WriteReq miss latency -system.cpu.dcache.WriteReq_avg_mshr_miss_latency 52999.834453 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 436281234 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 125837340000 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_avg_miss_latency 55999.840680 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 52999.840680 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 436281288 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 125834330000 # number of WriteReq miss cycles system.cpu.dcache.WriteReq_miss_rate 0.005124 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 2247102 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 119096034000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_misses 2247048 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 119093186000 # number of WriteReq MSHR miss cycles system.cpu.dcache.WriteReq_mshr_miss_rate 0.005124 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 2247102 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_mshr_misses 2247048 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 183.099497 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 183.121439 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 1677713078 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 32368.922185 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 29368.922185 # average overall mshr miss latency -system.cpu.dcache.demand_hits 1668242528 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 306551496000 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.005645 # miss rate for demand accesses -system.cpu.dcache.demand_misses 9470550 # number of demand (read+write) misses +system.cpu.dcache.demand_avg_miss_latency 32370.287021 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 29370.287021 # average overall mshr miss latency +system.cpu.dcache.demand_hits 1668243775 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 306524056000 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.005644 # miss rate for demand accesses +system.cpu.dcache.demand_misses 9469303 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 278139846000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.005645 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 9470550 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 278116147000 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.005644 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 9469303 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 1677713078 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 32368.922185 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 29368.922185 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 32370.287021 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 29370.287021 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 1668242528 # number of overall hits -system.cpu.dcache.overall_miss_latency 306551496000 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.005645 # miss rate for overall accesses -system.cpu.dcache.overall_misses 9470550 # number of overall misses +system.cpu.dcache.overall_hits 1668243775 # number of overall hits +system.cpu.dcache.overall_miss_latency 306524056000 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.005644 # miss rate for overall accesses +system.cpu.dcache.overall_misses 9469303 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 278139846000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.005645 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 9470550 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 278116147000 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.005644 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 9469303 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 9108982 # number of replacements -system.cpu.dcache.sampled_refs 9113078 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 9107896 # number of replacements +system.cpu.dcache.sampled_refs 9111992 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 4084.778553 # Cycle average of tags in use -system.cpu.dcache.total_refs 1668600000 # Total number of references to valid blocks. -system.cpu.dcache.warmup_cycle 58863931000 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 2244013 # number of writebacks +system.cpu.dcache.tagsinuse 4084.774232 # Cycle average of tags in use +system.cpu.dcache.total_refs 1668601086 # Total number of references to valid blocks. +system.cpu.dcache.warmup_cycle 58863918000 # Cycle when the warmup percentage was hit. +system.cpu.dcache.writebacks 2243955 # number of writebacks system.cpu.icache.ReadReq_accesses 4013232890 # number of ReadReq accesses(hits+misses) system.cpu.icache.ReadReq_avg_miss_latency 56000 # average ReadReq miss latency system.cpu.icache.ReadReq_avg_mshr_miss_latency 53000 # average ReadReq mshr miss latency @@ -120,86 +120,86 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 10 # number of replacements system.cpu.icache.sampled_refs 675 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 555.573306 # Cycle average of tags in use +system.cpu.icache.tagsinuse 555.573148 # Cycle average of tags in use system.cpu.icache.total_refs 4013232215 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 1889630 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_accesses 1889737 # number of ReadExReq accesses(hits+misses) system.cpu.l2cache.ReadExReq_avg_miss_latency 52000 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 98260760000 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 98266324000 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 1889630 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 75585200000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 1889737 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 75589480000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 1889630 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 7224123 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_mshr_misses 1889737 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 7222930 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 5328546 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 98570004000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.262395 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 1895577 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 75823080000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.262395 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 1895577 # number of ReadReq MSHR misses -system.cpu.l2cache.UpgradeReq_accesses 357472 # number of UpgradeReq accesses(hits+misses) -system.cpu.l2cache.UpgradeReq_avg_miss_latency 51945.886671 # average UpgradeReq miss latency +system.cpu.l2cache.ReadReq_hits 5327537 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 98560436000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.262413 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 1895393 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 75815720000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.262413 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 1895393 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 357311 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.UpgradeReq_avg_miss_latency 51947.899729 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency -system.cpu.l2cache.UpgradeReq_miss_latency 18569200000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_latency 18561556000 # number of UpgradeReq miss cycles system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_misses 357472 # number of UpgradeReq misses -system.cpu.l2cache.UpgradeReq_mshr_miss_latency 14298880000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_misses 357311 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 14292440000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_mshr_misses 357472 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 2244013 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 2244013 # number of Writeback hits +system.cpu.l2cache.UpgradeReq_mshr_misses 357311 # number of UpgradeReq MSHR misses +system.cpu.l2cache.Writeback_accesses 2243955 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 2243955 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 2.381201 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 2.380966 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 9113753 # number of demand (read+write) accesses +system.cpu.l2cache.demand_accesses 9112667 # number of demand (read+write) accesses system.cpu.l2cache.demand_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 5328546 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 196830764000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.415329 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 3785207 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 5327537 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 196826760000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.415370 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 3785130 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 151408280000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.415329 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 3785207 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 151405200000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.415370 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 3785130 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 9113753 # number of overall (read+write) accesses +system.cpu.l2cache.overall_accesses 9112667 # number of overall (read+write) accesses system.cpu.l2cache.overall_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 5328546 # number of overall hits -system.cpu.l2cache.overall_miss_latency 196830764000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.415329 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 3785207 # number of overall misses +system.cpu.l2cache.overall_hits 5327537 # number of overall hits +system.cpu.l2cache.overall_miss_latency 196826760000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.415370 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 3785130 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 151408280000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.415329 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 3785207 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 151405200000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.415370 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 3785130 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.l2cache.replacements 2772128 # number of replacements -system.cpu.l2cache.sampled_refs 2798338 # Sample count of references to valid blocks. +system.cpu.l2cache.replacements 2771977 # number of replacements +system.cpu.l2cache.sampled_refs 2798150 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 25742.940388 # Cycle average of tags in use -system.cpu.l2cache.total_refs 6663406 # Total number of references to valid blocks. -system.cpu.l2cache.warmup_cycle 4737814312000 # Cycle when the warmup percentage was hit. -system.cpu.l2cache.writebacks 1199171 # number of writebacks +system.cpu.l2cache.tagsinuse 25743.015890 # Cycle average of tags in use +system.cpu.l2cache.total_refs 6662299 # Total number of references to valid blocks. +system.cpu.l2cache.warmup_cycle 4737770578000 # Cycle when the warmup percentage was hit. +system.cpu.l2cache.writebacks 1199166 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 11976128076 # number of cpu cycles simulated +system.cpu.numCycles 11976075690 # number of cpu cycles simulated system.cpu.num_insts 4653327894 # Number of instructions executed system.cpu.num_refs 1677713078 # Number of memory references system.cpu.workload.PROG:num_syscalls 46 # Number of system calls diff --git a/tests/long/60.bzip2/test.py b/tests/long/60.bzip2/test.py index 7fa3d1a07..fa74d0860 100644 --- a/tests/long/60.bzip2/test.py +++ b/tests/long/60.bzip2/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import bzip2_source workload = bzip2_source(isa, opsys, 'lgred') diff --git a/tests/long/70.twolf/ref/x86/linux/simple-timing/config.ini b/tests/long/70.twolf/ref/x86/linux/simple-timing/config.ini index f70defe2b..6cbe3be3b 100644 --- a/tests/long/70.twolf/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/70.twolf/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 @@ -152,7 +149,7 @@ type=ExeTracer [system.cpu.workload] type=LiveProcess cmd=twolf smred -cwd=build/X86_SE/tests/opt/long/70.twolf/x86/linux/simple-timing +cwd=build/X86_SE/tests/fast/long/70.twolf/x86/linux/simple-timing egid=100 env= errout=cerr diff --git a/tests/long/70.twolf/ref/x86/linux/simple-timing/simout b/tests/long/70.twolf/ref/x86/linux/simple-timing/simout index cfb8745b2..32ad08600 100755 --- a/tests/long/70.twolf/ref/x86/linux/simple-timing/simout +++ b/tests/long/70.twolf/ref/x86/linux/simple-timing/simout @@ -5,11 +5,11 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 17 2009 20:29:57 -M5 revision 84f7bdc43a4f 6605 default qtip tip x86fsdate.patch -M5 started Aug 17 2009 20:42:16 -M5 executing on tater -command line: build/X86_SE/m5.opt -d build/X86_SE/tests/opt/long/70.twolf/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/opt/long/70.twolf/x86/linux/simple-timing +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:37:25 +M5 executing on maize +command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/70.twolf/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/70.twolf/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -27,4 +27,4 @@ info: Increasing stack size by one page. 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 -122 123 124 Exiting @ tick 250961789000 because target called exit() +122 123 124 Exiting @ tick 250962019000 because target called exit() diff --git a/tests/long/70.twolf/ref/x86/linux/simple-timing/stats.txt b/tests/long/70.twolf/ref/x86/linux/simple-timing/stats.txt index d0361bdaa..96e63da4b 100644 --- a/tests/long/70.twolf/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/70.twolf/ref/x86/linux/simple-timing/stats.txt @@ -1,84 +1,84 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 489241 # Simulator instruction rate (inst/s) -host_mem_usage 228040 # Number of bytes of host memory used -host_seconds 448.51 # Real time elapsed on the host -host_tick_rate 559541126 # Simulator tick rate (ticks/s) +host_inst_rate 894535 # Simulator instruction rate (inst/s) +host_mem_usage 201656 # Number of bytes of host memory used +host_seconds 245.30 # Real time elapsed on the host +host_tick_rate 1023073835 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 219430973 # Number of instructions simulated sim_seconds 0.250962 # Number of seconds simulated -sim_ticks 250961789000 # Number of ticks simulated +sim_ticks 250962019000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 56682001 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 55873.040752 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 52873.040752 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 56681682 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 17823500 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_avg_miss_latency 55228.395062 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 52226.851852 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 56681677 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 17894000 # number of ReadReq miss cycles system.cpu.dcache.ReadReq_miss_rate 0.000006 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 319 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 16866500 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_misses 324 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 16921500 # number of ReadReq MSHR miss cycles system.cpu.dcache.ReadReq_mshr_miss_rate 0.000006 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 319 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_mshr_misses 324 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 20515729 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 56000 # average WriteReq miss latency system.cpu.dcache.WriteReq_avg_mshr_miss_latency 53000 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 20514128 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 89656000 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_hits 20514125 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 89824000 # number of WriteReq miss cycles system.cpu.dcache.WriteReq_miss_rate 0.000078 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 1601 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 84853000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_misses 1604 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 85012000 # number of WriteReq MSHR miss cycles system.cpu.dcache.WriteReq_mshr_miss_rate 0.000078 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 1601 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_mshr_misses 1604 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 40758.097149 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 40586.660358 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 77197730 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 55978.906250 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 52978.906250 # average overall mshr miss latency -system.cpu.dcache.demand_hits 77195810 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 107479500 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_avg_miss_latency 55870.331950 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 52870.072614 # average overall mshr miss latency +system.cpu.dcache.demand_hits 77195802 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 107718000 # number of demand (read+write) miss cycles system.cpu.dcache.demand_miss_rate 0.000025 # miss rate for demand accesses -system.cpu.dcache.demand_misses 1920 # number of demand (read+write) misses +system.cpu.dcache.demand_misses 1928 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 101719500 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_latency 101933500 # number of demand (read+write) MSHR miss cycles system.cpu.dcache.demand_mshr_miss_rate 0.000025 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 1920 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_misses 1928 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 77197730 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 55978.906250 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 52978.906250 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 55870.331950 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 52870.072614 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 77195810 # number of overall hits -system.cpu.dcache.overall_miss_latency 107479500 # number of overall miss cycles +system.cpu.dcache.overall_hits 77195802 # number of overall hits +system.cpu.dcache.overall_miss_latency 107718000 # number of overall miss cycles system.cpu.dcache.overall_miss_rate 0.000025 # miss rate for overall accesses -system.cpu.dcache.overall_misses 1920 # number of overall misses +system.cpu.dcache.overall_misses 1928 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 101719500 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_latency 101933500 # number of overall MSHR miss cycles system.cpu.dcache.overall_mshr_miss_rate 0.000025 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 1920 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_misses 1928 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 27 # number of replacements -system.cpu.dcache.sampled_refs 1894 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 40 # number of replacements +system.cpu.dcache.sampled_refs 1902 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 1362.582472 # Cycle average of tags in use -system.cpu.dcache.total_refs 77195836 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 1361.446792 # Cycle average of tags in use +system.cpu.dcache.total_refs 77195828 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 2 # number of writebacks +system.cpu.dcache.writebacks 7 # number of writebacks system.cpu.icache.ReadReq_accesses 173494375 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 39420.962931 # average ReadReq miss latency -system.cpu.icache.ReadReq_avg_mshr_miss_latency 36414.252237 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_avg_miss_latency 39420.856412 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 36414.145718 # average ReadReq mshr miss latency system.cpu.icache.ReadReq_hits 173489681 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 185042000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_latency 185041500 # number of ReadReq miss cycles system.cpu.icache.ReadReq_miss_rate 0.000027 # miss rate for ReadReq accesses system.cpu.icache.ReadReq_misses 4694 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_miss_latency 170928500 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_latency 170928000 # number of ReadReq MSHR miss cycles system.cpu.icache.ReadReq_mshr_miss_rate 0.000027 # mshr miss rate for ReadReq accesses system.cpu.icache.ReadReq_mshr_misses 4694 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked @@ -90,29 +90,29 @@ system.cpu.icache.blocked_cycles::no_mshrs 0 # system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed system.cpu.icache.demand_accesses 173494375 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 39420.962931 # average overall miss latency -system.cpu.icache.demand_avg_mshr_miss_latency 36414.252237 # average overall mshr miss latency +system.cpu.icache.demand_avg_miss_latency 39420.856412 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 36414.145718 # average overall mshr miss latency system.cpu.icache.demand_hits 173489681 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 185042000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_latency 185041500 # number of demand (read+write) miss cycles system.cpu.icache.demand_miss_rate 0.000027 # miss rate for demand accesses system.cpu.icache.demand_misses 4694 # number of demand (read+write) misses system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.icache.demand_mshr_miss_latency 170928500 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_latency 170928000 # number of demand (read+write) MSHR miss cycles system.cpu.icache.demand_mshr_miss_rate 0.000027 # mshr miss rate for demand accesses system.cpu.icache.demand_mshr_misses 4694 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.icache.overall_accesses 173494375 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 39420.962931 # average overall miss latency -system.cpu.icache.overall_avg_mshr_miss_latency 36414.252237 # average overall mshr miss latency +system.cpu.icache.overall_avg_miss_latency 39420.856412 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 36414.145718 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.icache.overall_hits 173489681 # number of overall hits -system.cpu.icache.overall_miss_latency 185042000 # number of overall miss cycles +system.cpu.icache.overall_miss_latency 185041500 # number of overall miss cycles system.cpu.icache.overall_miss_rate 0.000027 # miss rate for overall accesses system.cpu.icache.overall_misses 4694 # number of overall misses system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.icache.overall_mshr_miss_latency 170928500 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_latency 170928000 # number of overall MSHR miss cycles system.cpu.icache.overall_mshr_miss_rate 0.000027 # mshr miss rate for overall accesses system.cpu.icache.overall_mshr_misses 4694 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles @@ -120,29 +120,29 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 2836 # number of replacements system.cpu.icache.sampled_refs 4694 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 1455.283776 # Cycle average of tags in use +system.cpu.icache.tagsinuse 1455.283940 # Cycle average of tags in use system.cpu.icache.total_refs 173489681 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 1575 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_accesses 1578 # number of ReadExReq accesses(hits+misses) system.cpu.l2cache.ReadExReq_avg_miss_latency 52000 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 81900000 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 82056000 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 1575 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 63000000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 1578 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 63120000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 1575 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 5013 # number of ReadReq accesses(hits+misses) -system.cpu.l2cache.ReadReq_avg_miss_latency 52005.066498 # average ReadReq miss latency +system.cpu.l2cache.ReadExReq_mshr_misses 1578 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 5018 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 52004.908170 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 1855 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 164232000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.629962 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_hits 1860 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 164231500 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.629334 # miss rate for ReadReq accesses system.cpu.l2cache.ReadReq_misses 3158 # number of ReadReq misses system.cpu.l2cache.ReadReq_mshr_miss_latency 126320000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.629962 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.629334 # mshr miss rate for ReadReq accesses system.cpu.l2cache.ReadReq_mshr_misses 3158 # number of ReadReq MSHR misses system.cpu.l2cache.UpgradeReq_accesses 26 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 52000 # average UpgradeReq miss latency @@ -153,53 +153,53 @@ system.cpu.l2cache.UpgradeReq_misses 26 # nu system.cpu.l2cache.UpgradeReq_mshr_miss_latency 1040000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses system.cpu.l2cache.UpgradeReq_mshr_misses 26 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 2 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 2 # number of Writeback hits +system.cpu.l2cache.Writeback_accesses 7 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 7 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 0.591895 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 0.593112 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 6588 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 52003.380520 # average overall miss latency +system.cpu.l2cache.demand_accesses 6596 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 52003.272804 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 1855 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 246132000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.718427 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 4733 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 1860 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 246287500 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.718011 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 4736 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 189320000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.718427 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 4733 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 189440000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.718011 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 4736 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 6588 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 52003.380520 # average overall miss latency +system.cpu.l2cache.overall_accesses 6596 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 52003.272804 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 1855 # number of overall hits -system.cpu.l2cache.overall_miss_latency 246132000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.718427 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 4733 # number of overall misses +system.cpu.l2cache.overall_hits 1860 # number of overall hits +system.cpu.l2cache.overall_miss_latency 246287500 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.718011 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 4736 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 189320000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.718427 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 4733 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 189440000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.718011 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 4736 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.l2cache.replacements 0 # number of replacements -system.cpu.l2cache.sampled_refs 3134 # Sample count of references to valid blocks. +system.cpu.l2cache.sampled_refs 3136 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 2033.146295 # Cycle average of tags in use -system.cpu.l2cache.total_refs 1855 # Total number of references to valid blocks. +system.cpu.l2cache.tagsinuse 2033.169065 # Cycle average of tags in use +system.cpu.l2cache.total_refs 1860 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.l2cache.writebacks 0 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 501923578 # number of cpu cycles simulated +system.cpu.numCycles 501924038 # number of cpu cycles simulated system.cpu.num_insts 219430973 # Number of instructions executed system.cpu.num_refs 77165298 # Number of memory references system.cpu.workload.PROG:num_syscalls 400 # Number of system calls diff --git a/tests/long/70.twolf/test.py b/tests/long/70.twolf/test.py index 85b106eb4..761ec8b2e 100644 --- a/tests/long/70.twolf/test.py +++ b/tests/long/70.twolf/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import twolf import os diff --git a/tests/quick/00.hello/ref/mips/linux/inorder-timing/simout b/tests/quick/00.hello/ref/mips/linux/inorder-timing/simout index 56a68daea..f04692a1f 100755 --- a/tests/quick/00.hello/ref/mips/linux/inorder-timing/simout +++ b/tests/quick/00.hello/ref/mips/linux/inorder-timing/simout @@ -5,13 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled May 13 2009 01:40:41 -M5 revision 4c418376e894 6202 default tip -M5 started May 13 2009 01:40:42 +M5 compiled Sep 24 2009 12:19:09 +M5 revision 9bc3e4611009+ 6661+ default tip +M5 started Sep 24 2009 12:19:46 M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/inorder-timing -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/inorder-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 29437500 because target called exit() +Exiting @ tick 29521500 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/inorder-timing/stats.txt b/tests/quick/00.hello/ref/mips/linux/inorder-timing/stats.txt index 577875f3a..a47f185bc 100644 --- a/tests/quick/00.hello/ref/mips/linux/inorder-timing/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/inorder-timing/stats.txt @@ -1,44 +1,44 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 23976 # Simulator instruction rate (inst/s) -host_mem_usage 152688 # Number of bytes of host memory used -host_seconds 0.24 # Real time elapsed on the host -host_tick_rate 124659634 # Simulator tick rate (ticks/s) +host_inst_rate 29581 # Simulator instruction rate (inst/s) +host_mem_usage 155804 # Number of bytes of host memory used +host_seconds 0.19 # Real time elapsed on the host +host_tick_rate 153369596 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated -sim_seconds 0.000029 # Number of seconds simulated -sim_ticks 29437500 # Number of ticks simulated -system.cpu.AGEN-Unit.instReqsProcessed 2055 # Number of Instructions Requests that completed in this resource. -system.cpu.Branch-Predictor.instReqsProcessed 5657 # Number of Instructions Requests that completed in this resource. -system.cpu.Branch-Predictor.predictedNotTaken 783 # Number of Branches Predicted As Not Taken (False). +sim_insts 5685 # Number of instructions simulated +sim_seconds 0.000030 # Number of seconds simulated +sim_ticks 29521500 # Number of ticks simulated +system.cpu.AGEN-Unit.instReqsProcessed 2058 # Number of Instructions Requests that completed in this resource. +system.cpu.Branch-Predictor.instReqsProcessed 5686 # Number of Instructions Requests that completed in this resource. +system.cpu.Branch-Predictor.predictedNotTaken 789 # Number of Branches Predicted As Not Taken (False). system.cpu.Branch-Predictor.predictedTaken 96 # Number of Branches Predicted As Taken (True). -system.cpu.Decode-Unit.instReqsProcessed 5657 # Number of Instructions Requests that completed in this resource. -system.cpu.Execution-Unit.instReqsProcessed 3598 # Number of Instructions Requests that completed in this resource. -system.cpu.Execution-Unit.predictedNotTakenIncorrect 515 # Number of Branches Incorrectly Predicted As Not Taken). +system.cpu.Decode-Unit.instReqsProcessed 5686 # Number of Instructions Requests that completed in this resource. +system.cpu.Execution-Unit.instReqsProcessed 3624 # Number of Instructions Requests that completed in this resource. +system.cpu.Execution-Unit.predictedNotTakenIncorrect 516 # Number of Branches Incorrectly Predicted As Not Taken). system.cpu.Execution-Unit.predictedTakenIncorrect 34 # Number of Branches Incorrectly Predicted As Taken. system.cpu.Fetch-Buffer-T0.instReqsProcessed 0 # Number of Instructions Requests that completed in this resource. system.cpu.Fetch-Buffer-T0.instsBypassed 0 # Number of Instructions Bypassed. system.cpu.Fetch-Buffer-T1.instReqsProcessed 0 # Number of Instructions Requests that completed in this resource. system.cpu.Fetch-Buffer-T1.instsBypassed 0 # Number of Instructions Bypassed. -system.cpu.Fetch-Seq-Unit.instReqsProcessed 11315 # Number of Instructions Requests that completed in this resource. -system.cpu.Graduation-Unit.instReqsProcessed 5656 # Number of Instructions Requests that completed in this resource. +system.cpu.Fetch-Seq-Unit.instReqsProcessed 11373 # Number of Instructions Requests that completed in this resource. +system.cpu.Graduation-Unit.instReqsProcessed 5685 # Number of Instructions Requests that completed in this resource. system.cpu.Mult-Div-Unit.divInstReqsProcessed 1 # Number of Divide Requests Processed. system.cpu.Mult-Div-Unit.instReqsProcessed 8 # Number of Instructions Requests that completed in this resource. system.cpu.Mult-Div-Unit.multInstReqsProcessed 3 # Number of Multiply Requests Processed. -system.cpu.RegFile-Manager.instReqsProcessed 10420 # Number of Instructions Requests that completed in this resource. -system.cpu.committedInsts 5656 # Number of Instructions Simulated (Per-Thread) -system.cpu.committedInsts_total 5656 # Number of Instructions Simulated (Total) -system.cpu.cpi 10.409477 # CPI: Cycles Per Instruction (Per-Thread) -system.cpu.cpi_total 10.409477 # CPI: Total CPI of All Threads -system.cpu.dcache.ReadReq_accesses 1131 # number of ReadReq accesses(hits+misses) +system.cpu.RegFile-Manager.instReqsProcessed 10479 # Number of Instructions Requests that completed in this resource. +system.cpu.committedInsts 5685 # Number of Instructions Simulated (Per-Thread) +system.cpu.committedInsts_total 5685 # Number of Instructions Simulated (Total) +system.cpu.cpi 10.385928 # CPI: Cycles Per Instruction (Per-Thread) +system.cpu.cpi_total 10.385928 # CPI: Total CPI of All Threads +system.cpu.dcache.ReadReq_accesses 1134 # number of ReadReq accesses(hits+misses) system.cpu.dcache.ReadReq_avg_miss_latency 56207.317073 # average ReadReq miss latency system.cpu.dcache.ReadReq_avg_mshr_miss_latency 53207.317073 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 1049 # number of ReadReq hits +system.cpu.dcache.ReadReq_hits 1052 # number of ReadReq hits system.cpu.dcache.ReadReq_miss_latency 4609000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.072502 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_miss_rate 0.072310 # miss rate for ReadReq accesses system.cpu.dcache.ReadReq_misses 82 # number of ReadReq misses system.cpu.dcache.ReadReq_mshr_miss_latency 4363000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.072502 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_miss_rate 0.072310 # mshr miss rate for ReadReq accesses system.cpu.dcache.ReadReq_mshr_misses 82 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 924 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 56554.687500 # average WriteReq miss latency @@ -52,48 +52,48 @@ system.cpu.dcache.WriteReq_mshr_miss_rate 0.069264 # m system.cpu.dcache.WriteReq_mshr_misses 64 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 14.568182 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 14.590909 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed -system.cpu.dcache.demand_accesses 2055 # number of demand (read+write) accesses +system.cpu.dcache.demand_accesses 2058 # number of demand (read+write) accesses system.cpu.dcache.demand_avg_miss_latency 56359.589041 # average overall miss latency system.cpu.dcache.demand_avg_mshr_miss_latency 53359.589041 # average overall mshr miss latency -system.cpu.dcache.demand_hits 1909 # number of demand (read+write) hits +system.cpu.dcache.demand_hits 1912 # number of demand (read+write) hits system.cpu.dcache.demand_miss_latency 8228500 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.071046 # miss rate for demand accesses +system.cpu.dcache.demand_miss_rate 0.070943 # miss rate for demand accesses system.cpu.dcache.demand_misses 146 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits system.cpu.dcache.demand_mshr_miss_latency 7790500 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.071046 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_miss_rate 0.070943 # mshr miss rate for demand accesses system.cpu.dcache.demand_mshr_misses 146 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.dcache.overall_accesses 2055 # number of overall (read+write) accesses +system.cpu.dcache.overall_accesses 2058 # number of overall (read+write) accesses system.cpu.dcache.overall_avg_miss_latency 56359.589041 # average overall miss latency system.cpu.dcache.overall_avg_mshr_miss_latency 53359.589041 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 1909 # number of overall hits +system.cpu.dcache.overall_hits 1912 # number of overall hits system.cpu.dcache.overall_miss_latency 8228500 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.071046 # miss rate for overall accesses +system.cpu.dcache.overall_miss_rate 0.070943 # miss rate for overall accesses system.cpu.dcache.overall_misses 146 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits system.cpu.dcache.overall_mshr_miss_latency 7790500 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.071046 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_miss_rate 0.070943 # mshr miss rate for overall accesses system.cpu.dcache.overall_mshr_misses 146 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.dcache.replacements 0 # number of replacements system.cpu.dcache.sampled_refs 132 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 84.205216 # Cycle average of tags in use -system.cpu.dcache.total_refs 1923 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 84.209307 # Cycle average of tags in use +system.cpu.dcache.total_refs 1926 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.dcache.writebacks 0 # number of writebacks -system.cpu.dcache_port.instReqsProcessed 2054 # Number of Instructions Requests that completed in this resource. +system.cpu.dcache_port.instReqsProcessed 2057 # Number of Instructions Requests that completed in this resource. system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits system.cpu.dtb.misses 0 # DTB misses @@ -103,62 +103,62 @@ system.cpu.dtb.read_misses 0 # DT system.cpu.dtb.write_accesses 0 # DTB write accesses system.cpu.dtb.write_hits 0 # DTB write hits system.cpu.dtb.write_misses 0 # DTB write misses -system.cpu.icache.ReadReq_accesses 5658 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 55772.277228 # average ReadReq miss latency -system.cpu.icache.ReadReq_avg_mshr_miss_latency 52772.277228 # average ReadReq mshr miss latency -system.cpu.icache.ReadReq_hits 5355 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 16899000 # number of ReadReq miss cycles -system.cpu.icache.ReadReq_miss_rate 0.053552 # miss rate for ReadReq accesses -system.cpu.icache.ReadReq_misses 303 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_miss_latency 15990000 # number of ReadReq MSHR miss cycles -system.cpu.icache.ReadReq_mshr_miss_rate 0.053552 # mshr miss rate for ReadReq accesses -system.cpu.icache.ReadReq_mshr_misses 303 # number of ReadReq MSHR misses +system.cpu.icache.ReadReq_accesses 5687 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 55773.026316 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 52773.026316 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_hits 5383 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 16955000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.053455 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 304 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_miss_latency 16043000 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_rate 0.053455 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_misses 304 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.icache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.icache.avg_refs 17.673267 # Average number of references to valid blocks. +system.cpu.icache.avg_refs 17.707237 # Average number of references to valid blocks. system.cpu.icache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed -system.cpu.icache.demand_accesses 5658 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 55772.277228 # average overall miss latency -system.cpu.icache.demand_avg_mshr_miss_latency 52772.277228 # average overall mshr miss latency -system.cpu.icache.demand_hits 5355 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 16899000 # number of demand (read+write) miss cycles -system.cpu.icache.demand_miss_rate 0.053552 # miss rate for demand accesses -system.cpu.icache.demand_misses 303 # number of demand (read+write) misses +system.cpu.icache.demand_accesses 5687 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 55773.026316 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 52773.026316 # average overall mshr miss latency +system.cpu.icache.demand_hits 5383 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 16955000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.053455 # miss rate for demand accesses +system.cpu.icache.demand_misses 304 # number of demand (read+write) misses system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.icache.demand_mshr_miss_latency 15990000 # number of demand (read+write) MSHR miss cycles -system.cpu.icache.demand_mshr_miss_rate 0.053552 # mshr miss rate for demand accesses -system.cpu.icache.demand_mshr_misses 303 # number of demand (read+write) MSHR misses +system.cpu.icache.demand_mshr_miss_latency 16043000 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_rate 0.053455 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_misses 304 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.icache.overall_accesses 5658 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 55772.277228 # average overall miss latency -system.cpu.icache.overall_avg_mshr_miss_latency 52772.277228 # average overall mshr miss latency +system.cpu.icache.overall_accesses 5687 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 55773.026316 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 52773.026316 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.icache.overall_hits 5355 # number of overall hits -system.cpu.icache.overall_miss_latency 16899000 # number of overall miss cycles -system.cpu.icache.overall_miss_rate 0.053552 # miss rate for overall accesses -system.cpu.icache.overall_misses 303 # number of overall misses +system.cpu.icache.overall_hits 5383 # number of overall hits +system.cpu.icache.overall_miss_latency 16955000 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.053455 # miss rate for overall accesses +system.cpu.icache.overall_misses 304 # number of overall misses system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.icache.overall_mshr_miss_latency 15990000 # number of overall MSHR miss cycles -system.cpu.icache.overall_mshr_miss_rate 0.053552 # mshr miss rate for overall accesses -system.cpu.icache.overall_mshr_misses 303 # number of overall MSHR misses +system.cpu.icache.overall_mshr_miss_latency 16043000 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_rate 0.053455 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_misses 304 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.icache.replacements 13 # number of replacements -system.cpu.icache.sampled_refs 303 # Sample count of references to valid blocks. +system.cpu.icache.sampled_refs 304 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 135.958324 # Cycle average of tags in use -system.cpu.icache.total_refs 5355 # Total number of references to valid blocks. +system.cpu.icache.tagsinuse 136.385131 # Cycle average of tags in use +system.cpu.icache.total_refs 5383 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks -system.cpu.icache_port.instReqsProcessed 5657 # Number of Instructions Requests that completed in this resource. -system.cpu.ipc 0.096066 # IPC: Instructions Per Cycle (Per-Thread) -system.cpu.ipc_total 0.096066 # IPC: Total IPC of All Threads +system.cpu.icache_port.instReqsProcessed 5686 # Number of Instructions Requests that completed in this resource. +system.cpu.ipc 0.096284 # IPC: Instructions Per Cycle (Per-Thread) +system.cpu.ipc_total 0.096284 # IPC: Total IPC of All Threads system.cpu.itb.accesses 0 # DTB accesses system.cpu.itb.hits 0 # DTB hits system.cpu.itb.misses 0 # DTB misses @@ -177,16 +177,16 @@ system.cpu.l2cache.ReadExReq_misses 50 # nu system.cpu.l2cache.ReadExReq_mshr_miss_latency 2004000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses system.cpu.l2cache.ReadExReq_mshr_misses 50 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 385 # number of ReadReq accesses(hits+misses) -system.cpu.l2cache.ReadReq_avg_miss_latency 52052.219321 # average ReadReq miss latency -system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40026.109661 # average ReadReq mshr miss latency +system.cpu.l2cache.ReadReq_accesses 386 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 52052.083333 # average ReadReq miss latency +system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40026.041667 # average ReadReq mshr miss latency system.cpu.l2cache.ReadReq_hits 2 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 19936000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.994805 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 383 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 15330000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.994805 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 383 # number of ReadReq MSHR misses +system.cpu.l2cache.ReadReq_miss_latency 19988000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.994819 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 384 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 15370000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.994819 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 384 # number of ReadReq MSHR misses system.cpu.l2cache.UpgradeReq_accesses 14 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 52535.714286 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40071.428571 # average UpgradeReq mshr miss latency @@ -198,53 +198,53 @@ system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 system.cpu.l2cache.UpgradeReq_mshr_misses 14 # number of UpgradeReq MSHR misses system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 0.005420 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 0.005405 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 435 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 52103.926097 # average overall miss latency -system.cpu.l2cache.demand_avg_mshr_miss_latency 40032.332564 # average overall mshr miss latency +system.cpu.l2cache.demand_accesses 436 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 52103.686636 # average overall miss latency +system.cpu.l2cache.demand_avg_mshr_miss_latency 40032.258065 # average overall mshr miss latency system.cpu.l2cache.demand_hits 2 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 22561000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.995402 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 433 # number of demand (read+write) misses +system.cpu.l2cache.demand_miss_latency 22613000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.995413 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 434 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 17334000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.995402 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 433 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 17374000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.995413 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 434 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 435 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 52103.926097 # average overall miss latency -system.cpu.l2cache.overall_avg_mshr_miss_latency 40032.332564 # average overall mshr miss latency +system.cpu.l2cache.overall_accesses 436 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 52103.686636 # average overall miss latency +system.cpu.l2cache.overall_avg_mshr_miss_latency 40032.258065 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.l2cache.overall_hits 2 # number of overall hits -system.cpu.l2cache.overall_miss_latency 22561000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.995402 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 433 # number of overall misses +system.cpu.l2cache.overall_miss_latency 22613000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.995413 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 434 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 17334000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.995402 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 433 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 17374000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.995413 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 434 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.l2cache.replacements 0 # number of replacements -system.cpu.l2cache.sampled_refs 369 # Sample count of references to valid blocks. +system.cpu.l2cache.sampled_refs 370 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 183.249501 # Cycle average of tags in use +system.cpu.l2cache.tagsinuse 183.672228 # Cycle average of tags in use system.cpu.l2cache.total_refs 2 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.l2cache.writebacks 0 # number of writebacks -system.cpu.numCycles 58876 # number of cpu cycles simulated +system.cpu.numCycles 59044 # number of cpu cycles simulated system.cpu.smtCommittedInsts 0 # Number of SMT Instructions Simulated (Per-Thread) system.cpu.smtCycles 0 # Total number of cycles that the CPU was simultaneous multithreading.(SMT) system.cpu.smt_cpi no_value # CPI: Total SMT-CPI system.cpu.smt_ipc no_value # IPC: Total SMT-IPC -system.cpu.threadCycles 58876 # Total Number of Cycles A Thread Was Active in CPU (Per-Thread) +system.cpu.threadCycles 59044 # Total Number of Cycles A Thread Was Active in CPU (Per-Thread) system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/mips/linux/o3-timing/config.ini b/tests/quick/00.hello/ref/mips/linux/o3-timing/config.ini index 9e32dcc7f..b3bdddcfe 100644 --- a/tests/quick/00.hello/ref/mips/linux/o3-timing/config.ini +++ b/tests/quick/00.hello/ref/mips/linux/o3-timing/config.ini @@ -412,7 +412,7 @@ egid=100 env= errout=cerr euid=100 -executable=/dist/m5/regression/test-progs/hello/bin/mips/linux/hello +executable=tests/test-progs/hello/bin/mips/linux/hello gid=100 input=cin max_stack_size=67108864 diff --git a/tests/quick/00.hello/ref/mips/linux/o3-timing/simout b/tests/quick/00.hello/ref/mips/linux/o3-timing/simout index 5aef74b1c..9562c954f 100755 --- a/tests/quick/00.hello/ref/mips/linux/o3-timing/simout +++ b/tests/quick/00.hello/ref/mips/linux/o3-timing/simout @@ -5,13 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Jul 6 2009 11:05:29 -M5 revision d3635cac686a 6289 default ruby_refs.diff qtip tip -M5 started Jul 6 2009 11:11:08 -M5 executing on maize +M5 compiled Sep 24 2009 12:19:09 +M5 revision 9bc3e4611009+ 6661+ default tip +M5 started Sep 24 2009 12:19:46 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/o3-timing -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/o3-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 13881500 because target called exit() +Exiting @ tick 13914500 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/o3-timing/stats.txt b/tests/quick/00.hello/ref/mips/linux/o3-timing/stats.txt index 6d8206a5c..bdce7b5d3 100644 --- a/tests/quick/00.hello/ref/mips/linux/o3-timing/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/o3-timing/stats.txt @@ -1,65 +1,65 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 27478 # Simulator instruction rate (inst/s) -host_mem_usage 190884 # Number of bytes of host memory used -host_seconds 0.18 # Real time elapsed on the host -host_tick_rate 75816661 # Simulator tick rate (ticks/s) +host_inst_rate 59567 # Simulator instruction rate (inst/s) +host_mem_usage 155776 # Number of bytes of host memory used +host_seconds 0.09 # Real time elapsed on the host +host_tick_rate 163592222 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5024 # Number of instructions simulated +sim_insts 5049 # Number of instructions simulated sim_seconds 0.000014 # Number of seconds simulated -sim_ticks 13881500 # Number of ticks simulated +sim_ticks 13914500 # Number of ticks simulated system.cpu.BPredUnit.BTBCorrect 0 # Number of correct BTB predictions (this stat may not work properly. -system.cpu.BPredUnit.BTBHits 549 # Number of BTB hits -system.cpu.BPredUnit.BTBLookups 1924 # Number of BTB lookups +system.cpu.BPredUnit.BTBHits 552 # Number of BTB hits +system.cpu.BPredUnit.BTBLookups 1939 # Number of BTB lookups system.cpu.BPredUnit.RASInCorrect 53 # Number of incorrect RAS predictions. -system.cpu.BPredUnit.condIncorrect 721 # Number of conditional branches incorrect -system.cpu.BPredUnit.condPredicted 1540 # Number of conditional branches predicted -system.cpu.BPredUnit.lookups 2339 # Number of BP lookups -system.cpu.BPredUnit.usedRAS 384 # Number of times the RAS was used to get a target. -system.cpu.commit.COM:branches 879 # Number of branches committed +system.cpu.BPredUnit.condIncorrect 722 # Number of conditional branches incorrect +system.cpu.BPredUnit.condPredicted 1555 # Number of conditional branches predicted +system.cpu.BPredUnit.lookups 2357 # Number of BP lookups +system.cpu.BPredUnit.usedRAS 387 # Number of times the RAS was used to get a target. +system.cpu.commit.COM:branches 885 # Number of branches committed system.cpu.commit.COM:bw_lim_events 63 # number cycles where commit BW limit reached system.cpu.commit.COM:bw_limited 0 # number of insts not committed due to BW limits -system.cpu.commit.COM:committed_per_cycle::samples 14165 # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::mean 0.399223 # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::stdev 1.126414 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::samples 14230 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::mean 0.399438 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::stdev 1.125719 # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::underflows 0 0.00% 0.00% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::0-1 11701 82.61% 82.61% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::1-2 1166 8.23% 90.84% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::2-3 493 3.48% 94.32% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::3-4 279 1.97% 96.29% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::4-5 290 2.05% 98.33% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::5-6 74 0.52% 98.86% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::6-7 61 0.43% 99.29% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::0-1 11753 82.59% 82.59% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::1-2 1168 8.21% 90.80% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::2-3 499 3.51% 94.31% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::3-4 284 2.00% 96.30% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::4-5 291 2.04% 98.35% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::5-6 72 0.51% 98.85% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::6-7 62 0.44% 99.29% # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::7-8 38 0.27% 99.56% # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::8 63 0.44% 100.00% # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::overflows 0 0.00% 100.00% # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::min_value 0 # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::max_value 8 # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::total 14165 # Number of insts commited each cycle -system.cpu.commit.COM:count 5655 # Number of instructions committed -system.cpu.commit.COM:loads 1130 # Number of loads committed +system.cpu.commit.COM:committed_per_cycle::total 14230 # Number of insts commited each cycle +system.cpu.commit.COM:count 5684 # Number of instructions committed +system.cpu.commit.COM:loads 1133 # Number of loads committed system.cpu.commit.COM:membars 0 # Number of memory barriers committed -system.cpu.commit.COM:refs 2054 # Number of memory references committed +system.cpu.commit.COM:refs 2057 # Number of memory references committed system.cpu.commit.COM:swp_count 0 # Number of s/w prefetches committed -system.cpu.commit.branchMispredicts 604 # The number of times a branch was mispredicted -system.cpu.commit.commitCommittedInsts 5655 # The number of committed instructions +system.cpu.commit.branchMispredicts 605 # The number of times a branch was mispredicted +system.cpu.commit.commitCommittedInsts 5684 # The number of committed instructions system.cpu.commit.commitNonSpecStalls 15 # The number of times commit has been forced to stall to communicate backwards -system.cpu.commit.commitSquashedInsts 5936 # The number of squashed insts skipped by commit -system.cpu.committedInsts 5024 # Number of Instructions Simulated -system.cpu.committedInsts_total 5024 # Number of Instructions Simulated -system.cpu.cpi 5.526274 # CPI: Cycles Per Instruction -system.cpu.cpi_total 5.526274 # CPI: Total CPI of All Threads -system.cpu.dcache.ReadReq_accesses 2286 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 33976.377953 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 36034.883721 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 2159 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 4315000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.055556 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 127 # number of ReadReq misses +system.cpu.commit.commitSquashedInsts 5973 # The number of squashed insts skipped by commit +system.cpu.committedInsts 5049 # Number of Instructions Simulated +system.cpu.committedInsts_total 5049 # Number of Instructions Simulated +system.cpu.cpi 5.511983 # CPI: Cycles Per Instruction +system.cpu.cpi_total 5.511983 # CPI: Total CPI of All Threads +system.cpu.dcache.ReadReq_accesses 2297 # number of ReadReq accesses(hits+misses) +system.cpu.dcache.ReadReq_avg_miss_latency 34007.812500 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 36022.988506 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 2169 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 4353000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.055725 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 128 # number of ReadReq misses system.cpu.dcache.ReadReq_mshr_hits 41 # number of ReadReq MSHR hits -system.cpu.dcache.ReadReq_mshr_miss_latency 3099000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.037620 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 86 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_mshr_miss_latency 3134000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.037875 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 87 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 924 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 27701.724138 # average WriteReq miss latency system.cpu.dcache.WriteReq_avg_mshr_miss_latency 36093.750000 # average WriteReq mshr miss latency @@ -73,54 +73,54 @@ system.cpu.dcache.WriteReq_mshr_miss_rate 0.069264 # m system.cpu.dcache.WriteReq_mshr_misses 64 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 20.970370 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 20.889706 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed -system.cpu.dcache.demand_accesses 3210 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 29612.709832 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 36060 # average overall mshr miss latency -system.cpu.dcache.demand_hits 2793 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 12348500 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.129907 # miss rate for demand accesses -system.cpu.dcache.demand_misses 417 # number of demand (read+write) misses +system.cpu.dcache.demand_accesses 3221 # number of demand (read+write) accesses +system.cpu.dcache.demand_avg_miss_latency 29632.775120 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 36052.980132 # average overall mshr miss latency +system.cpu.dcache.demand_hits 2803 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 12386500 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.129773 # miss rate for demand accesses +system.cpu.dcache.demand_misses 418 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 267 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 5409000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.046729 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 150 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 5444000 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.046880 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 151 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.dcache.overall_accesses 3210 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 29612.709832 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 36060 # average overall mshr miss latency +system.cpu.dcache.overall_accesses 3221 # number of overall (read+write) accesses +system.cpu.dcache.overall_avg_miss_latency 29632.775120 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 36052.980132 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 2793 # number of overall hits -system.cpu.dcache.overall_miss_latency 12348500 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.129907 # miss rate for overall accesses -system.cpu.dcache.overall_misses 417 # number of overall misses +system.cpu.dcache.overall_hits 2803 # number of overall hits +system.cpu.dcache.overall_miss_latency 12386500 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.129773 # miss rate for overall accesses +system.cpu.dcache.overall_misses 418 # number of overall misses system.cpu.dcache.overall_mshr_hits 267 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 5409000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.046729 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 150 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 5444000 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.046880 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 151 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.dcache.replacements 0 # number of replacements -system.cpu.dcache.sampled_refs 135 # Sample count of references to valid blocks. +system.cpu.dcache.sampled_refs 136 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 87.531358 # Cycle average of tags in use -system.cpu.dcache.total_refs 2831 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 87.690614 # Cycle average of tags in use +system.cpu.dcache.total_refs 2841 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.dcache.writebacks 0 # number of writebacks system.cpu.decode.DECODE:BlockedCycles 479 # Number of cycles decode is blocked system.cpu.decode.DECODE:BranchMispred 128 # Number of times decode detected a branch misprediction system.cpu.decode.DECODE:BranchResolved 128 # Number of times decode resolved a branch -system.cpu.decode.DECODE:DecodedInsts 14141 # Number of instructions handled by decode -system.cpu.decode.DECODE:IdleCycles 9863 # Number of cycles decode is idle -system.cpu.decode.DECODE:RunCycles 3823 # Number of cycles decode is running -system.cpu.decode.DECODE:SquashCycles 1052 # Number of cycles decode is squashing +system.cpu.decode.DECODE:DecodedInsts 14211 # Number of instructions handled by decode +system.cpu.decode.DECODE:IdleCycles 9912 # Number of cycles decode is idle +system.cpu.decode.DECODE:RunCycles 3839 # Number of cycles decode is running +system.cpu.decode.DECODE:SquashCycles 1056 # Number of cycles decode is squashing system.cpu.decode.DECODE:SquashedInsts 251 # Number of squashed instructions handled by decode system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits @@ -131,116 +131,116 @@ system.cpu.dtb.read_misses 0 # DT system.cpu.dtb.write_accesses 0 # DTB write accesses system.cpu.dtb.write_hits 0 # DTB write hits system.cpu.dtb.write_misses 0 # DTB write misses -system.cpu.fetch.Branches 2339 # Number of branches that fetch encountered -system.cpu.fetch.CacheLines 2162 # Number of cache lines fetched -system.cpu.fetch.Cycles 6161 # Number of cycles fetch has run and was not squashing or blocked +system.cpu.fetch.Branches 2357 # Number of branches that fetch encountered +system.cpu.fetch.CacheLines 2171 # Number of cache lines fetched +system.cpu.fetch.Cycles 6187 # Number of cycles fetch has run and was not squashing or blocked system.cpu.fetch.IcacheSquashes 360 # Number of outstanding Icache misses that were squashed -system.cpu.fetch.Insts 15261 # Number of instructions fetch has processed -system.cpu.fetch.SquashCycles 737 # Number of cycles fetch has spent squashing -system.cpu.fetch.branchRate 0.084246 # Number of branch fetches per cycle -system.cpu.fetch.icacheStallCycles 2162 # Number of cycles fetch is stalled on an Icache miss -system.cpu.fetch.predictedBranches 933 # Number of branches that fetch has predicted taken -system.cpu.fetch.rate 0.549669 # Number of inst fetches per cycle -system.cpu.fetch.rateDist::samples 15217 # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::mean 1.002892 # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::stdev 2.262712 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.Insts 15337 # Number of instructions fetch has processed +system.cpu.fetch.SquashCycles 738 # Number of cycles fetch has spent squashing +system.cpu.fetch.branchRate 0.084693 # Number of branch fetches per cycle +system.cpu.fetch.icacheStallCycles 2171 # Number of cycles fetch is stalled on an Icache miss +system.cpu.fetch.predictedBranches 939 # Number of branches that fetch has predicted taken +system.cpu.fetch.rate 0.551096 # Number of inst fetches per cycle +system.cpu.fetch.rateDist::samples 15286 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::mean 1.003336 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::stdev 2.263199 # Number of instructions fetched each cycle (Total) system.cpu.fetch.rateDist::underflows 0 0.00% 0.00% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::0-1 11225 73.77% 73.77% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::1-2 1766 11.61% 85.37% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::2-3 196 1.29% 86.66% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::3-4 137 0.90% 87.56% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::4-5 314 2.06% 89.62% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::5-6 113 0.74% 90.37% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::6-7 304 2.00% 92.36% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::7-8 249 1.64% 94.00% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::8 913 6.00% 100.00% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::0-1 11277 73.77% 73.77% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::1-2 1770 11.58% 85.35% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::2-3 198 1.30% 86.65% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::3-4 138 0.90% 87.55% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::4-5 316 2.07% 89.62% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::5-6 114 0.75% 90.36% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::6-7 306 2.00% 92.37% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::7-8 249 1.63% 93.99% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::8 918 6.01% 100.00% # Number of instructions fetched each cycle (Total) system.cpu.fetch.rateDist::overflows 0 0.00% 100.00% # Number of instructions fetched each cycle (Total) system.cpu.fetch.rateDist::min_value 0 # Number of instructions fetched each cycle (Total) system.cpu.fetch.rateDist::max_value 8 # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::total 15217 # Number of instructions fetched each cycle (Total) -system.cpu.icache.ReadReq_accesses 2162 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 35500 # average ReadReq miss latency +system.cpu.fetch.rateDist::total 15286 # Number of instructions fetched each cycle (Total) +system.cpu.icache.ReadReq_accesses 2171 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 35436.489607 # average ReadReq miss latency system.cpu.icache.ReadReq_avg_mshr_miss_latency 34915.151515 # average ReadReq mshr miss latency -system.cpu.icache.ReadReq_hits 1731 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 15300500 # number of ReadReq miss cycles -system.cpu.icache.ReadReq_miss_rate 0.199352 # miss rate for ReadReq accesses -system.cpu.icache.ReadReq_misses 431 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_hits 101 # number of ReadReq MSHR hits +system.cpu.icache.ReadReq_hits 1738 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 15344000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.199447 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 433 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_hits 103 # number of ReadReq MSHR hits system.cpu.icache.ReadReq_mshr_miss_latency 11522000 # number of ReadReq MSHR miss cycles -system.cpu.icache.ReadReq_mshr_miss_rate 0.152636 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_miss_rate 0.152004 # mshr miss rate for ReadReq accesses system.cpu.icache.ReadReq_mshr_misses 330 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.icache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.icache.avg_refs 5.245455 # Average number of references to valid blocks. +system.cpu.icache.avg_refs 5.266667 # Average number of references to valid blocks. system.cpu.icache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed -system.cpu.icache.demand_accesses 2162 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 35500 # average overall miss latency +system.cpu.icache.demand_accesses 2171 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 35436.489607 # average overall miss latency system.cpu.icache.demand_avg_mshr_miss_latency 34915.151515 # average overall mshr miss latency -system.cpu.icache.demand_hits 1731 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 15300500 # number of demand (read+write) miss cycles -system.cpu.icache.demand_miss_rate 0.199352 # miss rate for demand accesses -system.cpu.icache.demand_misses 431 # number of demand (read+write) misses -system.cpu.icache.demand_mshr_hits 101 # number of demand (read+write) MSHR hits +system.cpu.icache.demand_hits 1738 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 15344000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.199447 # miss rate for demand accesses +system.cpu.icache.demand_misses 433 # number of demand (read+write) misses +system.cpu.icache.demand_mshr_hits 103 # number of demand (read+write) MSHR hits system.cpu.icache.demand_mshr_miss_latency 11522000 # number of demand (read+write) MSHR miss cycles -system.cpu.icache.demand_mshr_miss_rate 0.152636 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_miss_rate 0.152004 # mshr miss rate for demand accesses system.cpu.icache.demand_mshr_misses 330 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.icache.overall_accesses 2162 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 35500 # average overall miss latency +system.cpu.icache.overall_accesses 2171 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 35436.489607 # average overall miss latency system.cpu.icache.overall_avg_mshr_miss_latency 34915.151515 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.icache.overall_hits 1731 # number of overall hits -system.cpu.icache.overall_miss_latency 15300500 # number of overall miss cycles -system.cpu.icache.overall_miss_rate 0.199352 # miss rate for overall accesses -system.cpu.icache.overall_misses 431 # number of overall misses -system.cpu.icache.overall_mshr_hits 101 # number of overall MSHR hits +system.cpu.icache.overall_hits 1738 # number of overall hits +system.cpu.icache.overall_miss_latency 15344000 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.199447 # miss rate for overall accesses +system.cpu.icache.overall_misses 433 # number of overall misses +system.cpu.icache.overall_mshr_hits 103 # number of overall MSHR hits system.cpu.icache.overall_mshr_miss_latency 11522000 # number of overall MSHR miss cycles -system.cpu.icache.overall_mshr_miss_rate 0.152636 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_miss_rate 0.152004 # mshr miss rate for overall accesses system.cpu.icache.overall_mshr_misses 330 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.icache.replacements 16 # number of replacements system.cpu.icache.sampled_refs 330 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 158.760808 # Cycle average of tags in use -system.cpu.icache.total_refs 1731 # Total number of references to valid blocks. +system.cpu.icache.tagsinuse 159.086288 # Cycle average of tags in use +system.cpu.icache.total_refs 1738 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks -system.cpu.idleCycles 12547 # Total number of cycles that the CPU has spent unscheduled due to idling -system.cpu.iew.EXEC:branches 1206 # Number of branches executed -system.cpu.iew.EXEC:nop 1806 # number of nop insts executed -system.cpu.iew.EXEC:rate 0.291349 # Inst execution rate -system.cpu.iew.EXEC:refs 3420 # number of memory reference insts executed +system.cpu.idleCycles 12544 # Total number of cycles that the CPU has spent unscheduled due to idling +system.cpu.iew.EXEC:branches 1216 # Number of branches executed +system.cpu.iew.EXEC:nop 1820 # number of nop insts executed +system.cpu.iew.EXEC:rate 0.292239 # Inst execution rate +system.cpu.iew.EXEC:refs 3432 # number of memory reference insts executed system.cpu.iew.EXEC:stores 1048 # Number of stores executed system.cpu.iew.EXEC:swp 0 # number of swp insts executed -system.cpu.iew.WB:consumers 4016 # num instructions consuming a value -system.cpu.iew.WB:count 7315 # cumulative count of insts written-back -system.cpu.iew.WB:fanout 0.694970 # average fanout of values written-back +system.cpu.iew.WB:consumers 4040 # num instructions consuming a value +system.cpu.iew.WB:count 7355 # cumulative count of insts written-back +system.cpu.iew.WB:fanout 0.694802 # average fanout of values written-back system.cpu.iew.WB:penalized 0 # number of instrctions required to write to 'other' IQ system.cpu.iew.WB:penalized_rate 0 # fraction of instructions written-back that wrote to 'other' IQ -system.cpu.iew.WB:producers 2791 # num instructions producing a value -system.cpu.iew.WB:rate 0.263471 # insts written-back per cycle -system.cpu.iew.WB:sent 7402 # cumulative count of insts sent to commit -system.cpu.iew.branchMispredicts 661 # Number of branch mispredicts detected at execute +system.cpu.iew.WB:producers 2807 # num instructions producing a value +system.cpu.iew.WB:rate 0.264283 # insts written-back per cycle +system.cpu.iew.WB:sent 7444 # cumulative count of insts sent to commit +system.cpu.iew.branchMispredicts 663 # Number of branch mispredicts detected at execute system.cpu.iew.iewBlockCycles 8 # Number of cycles IEW is blocking -system.cpu.iew.iewDispLoadInsts 2783 # Number of dispatched load instructions +system.cpu.iew.iewDispLoadInsts 2795 # Number of dispatched load instructions system.cpu.iew.iewDispNonSpecInsts 15 # Number of dispatched non-speculative instructions system.cpu.iew.iewDispSquashedInsts 968 # Number of squashed instructions skipped by dispatch system.cpu.iew.iewDispStoreInsts 1158 # Number of dispatched store instructions -system.cpu.iew.iewDispatchedInsts 11594 # Number of instructions dispatched to IQ -system.cpu.iew.iewExecLoadInsts 2372 # Number of load instructions executed +system.cpu.iew.iewDispatchedInsts 11660 # Number of instructions dispatched to IQ +system.cpu.iew.iewExecLoadInsts 2384 # Number of load instructions executed system.cpu.iew.iewExecSquashedInsts 531 # Number of squashed instructions skipped in execute -system.cpu.iew.iewExecutedInsts 8089 # Number of executed instructions +system.cpu.iew.iewExecutedInsts 8133 # Number of executed instructions system.cpu.iew.iewIQFullEvents 0 # Number of times the IQ has become full, causing a stall system.cpu.iew.iewIdleCycles 0 # Number of cycles IEW is idle system.cpu.iew.iewLSQFullEvents 1 # Number of times the LSQ has become full, causing a stall -system.cpu.iew.iewSquashCycles 1052 # Number of cycles IEW is squashing +system.cpu.iew.iewSquashCycles 1056 # Number of cycles IEW is squashing system.cpu.iew.iewUnblockCycles 0 # Number of cycles IEW is unblocking system.cpu.iew.lsq.thread.0.blockedLoads 0 # Number of blocked loads due to partial load-store forwarding system.cpu.iew.lsq.thread.0.cacheBlocked 0 # Number of times an access to memory failed due to the cache being blocked @@ -250,30 +250,30 @@ system.cpu.iew.lsq.thread.0.invAddrLoads 0 # Nu system.cpu.iew.lsq.thread.0.invAddrSwpfs 0 # Number of software prefetches ignored due to an invalid address system.cpu.iew.lsq.thread.0.memOrderViolation 22 # Number of memory ordering violations system.cpu.iew.lsq.thread.0.rescheduledLoads 0 # Number of loads that were rescheduled -system.cpu.iew.lsq.thread.0.squashedLoads 1653 # Number of loads squashed +system.cpu.iew.lsq.thread.0.squashedLoads 1662 # Number of loads squashed system.cpu.iew.lsq.thread.0.squashedStores 234 # Number of stores squashed system.cpu.iew.memOrderViolationEvents 22 # Number of memory order violations -system.cpu.iew.predictedNotTakenIncorrect 276 # Number of branches that were predicted not taken incorrectly -system.cpu.iew.predictedTakenIncorrect 385 # Number of branches that were predicted taken incorrectly -system.cpu.ipc 0.180954 # IPC: Instructions Per Cycle -system.cpu.ipc_total 0.180954 # IPC: Total IPC of All Threads +system.cpu.iew.predictedNotTakenIncorrect 277 # Number of branches that were predicted not taken incorrectly +system.cpu.iew.predictedTakenIncorrect 386 # Number of branches that were predicted taken incorrectly +system.cpu.ipc 0.181423 # IPC: Instructions Per Cycle +system.cpu.ipc_total 0.181423 # IPC: Total IPC of All Threads system.cpu.iq.ISSUE:FU_type_0::No_OpClass 0 0.00% 0.00% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::IntAlu 4988 57.87% 57.87% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::IntMult 5 0.06% 57.92% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::IntDiv 2 0.02% 57.95% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatAdd 2 0.02% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatCmp 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatCvt 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatMult 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatDiv 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatSqrt 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::MemRead 2560 29.70% 87.67% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::MemWrite 1063 12.33% 100.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntAlu 5020 57.94% 57.94% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntMult 5 0.06% 58.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntDiv 2 0.02% 58.02% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatAdd 2 0.02% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatCmp 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatCvt 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatMult 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatDiv 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatSqrt 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::MemRead 2572 29.69% 87.73% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::MemWrite 1063 12.27% 100.00% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::IprAccess 0 0.00% 100.00% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::InstPrefetch 0 0.00% 100.00% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::total 8620 # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::total 8664 # Type of FU issued system.cpu.iq.ISSUE:fu_busy_cnt 162 # FU busy when requested -system.cpu.iq.ISSUE:fu_busy_rate 0.018794 # FU busy rate (busy events/executed inst) +system.cpu.iq.ISSUE:fu_busy_rate 0.018698 # FU busy rate (busy events/executed inst) system.cpu.iq.ISSUE:fu_full::No_OpClass 0 0.00% 0.00% # attempts to use FU when none available system.cpu.iq.ISSUE:fu_full::IntAlu 10 6.17% 6.17% # attempts to use FU when none available system.cpu.iq.ISSUE:fu_full::IntMult 0 0.00% 6.17% # attempts to use FU when none available @@ -288,30 +288,30 @@ system.cpu.iq.ISSUE:fu_full::MemRead 98 60.49% 66.67% # at system.cpu.iq.ISSUE:fu_full::MemWrite 54 33.33% 100.00% # attempts to use FU when none available system.cpu.iq.ISSUE:fu_full::IprAccess 0 0.00% 100.00% # attempts to use FU when none available system.cpu.iq.ISSUE:fu_full::InstPrefetch 0 0.00% 100.00% # attempts to use FU when none available -system.cpu.iq.ISSUE:issued_per_cycle::samples 15217 # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::mean 0.566472 # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::stdev 1.217507 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::samples 15286 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::mean 0.566793 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::stdev 1.217668 # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::underflows 0 0.00% 0.00% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::0-1 11370 74.72% 74.72% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::1-2 1673 10.99% 85.71% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::2-3 787 5.17% 90.89% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::3-4 717 4.71% 95.60% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::4-5 332 2.18% 97.78% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::5-6 198 1.30% 99.08% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::0-1 11421 74.72% 74.72% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::1-2 1678 10.98% 85.69% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::2-3 792 5.18% 90.87% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::3-4 722 4.72% 95.60% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::4-5 333 2.18% 97.78% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::5-6 200 1.31% 99.08% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::6-7 91 0.60% 99.68% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::7-8 34 0.22% 99.90% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::8 15 0.10% 100.00% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::overflows 0 0.00% 100.00% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::min_value 0 # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::max_value 8 # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::total 15217 # Number of insts issued each cycle -system.cpu.iq.ISSUE:rate 0.310474 # Inst issue rate -system.cpu.iq.iqInstsAdded 9773 # Number of instructions added to the IQ (excludes non-spec) -system.cpu.iq.iqInstsIssued 8620 # Number of instructions issued +system.cpu.iq.ISSUE:issued_per_cycle::total 15286 # Number of insts issued each cycle +system.cpu.iq.ISSUE:rate 0.311319 # Inst issue rate +system.cpu.iq.iqInstsAdded 9825 # Number of instructions added to the IQ (excludes non-spec) +system.cpu.iq.iqInstsIssued 8664 # Number of instructions issued system.cpu.iq.iqNonSpecInstsAdded 15 # Number of non-speculative instructions added to the IQ -system.cpu.iq.iqSquashedInstsExamined 4182 # Number of squashed instructions iterated over during squash; mainly for profiling +system.cpu.iq.iqSquashedInstsExamined 4207 # Number of squashed instructions iterated over during squash; mainly for profiling system.cpu.iq.iqSquashedInstsIssued 30 # Number of squashed instructions issued -system.cpu.iq.iqSquashedOperandsExamined 2741 # Number of squashed operands that are examined and possibly removed from graph +system.cpu.iq.iqSquashedOperandsExamined 2761 # Number of squashed operands that are examined and possibly removed from graph system.cpu.itb.accesses 0 # DTB accesses system.cpu.itb.hits 0 # DTB hits system.cpu.itb.misses 0 # DTB misses @@ -330,16 +330,16 @@ system.cpu.l2cache.ReadExReq_misses 49 # nu system.cpu.l2cache.ReadExReq_mshr_miss_latency 1539000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses system.cpu.l2cache.ReadExReq_mshr_misses 49 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 416 # number of ReadReq accesses(hits+misses) -system.cpu.l2cache.ReadReq_avg_miss_latency 34308.252427 # average ReadReq miss latency -system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 31129.854369 # average ReadReq mshr miss latency +system.cpu.l2cache.ReadReq_accesses 417 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 34307.506053 # average ReadReq miss latency +system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 31130.750605 # average ReadReq mshr miss latency system.cpu.l2cache.ReadReq_hits 4 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 14135000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.990385 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 412 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 12825500 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.990385 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 412 # number of ReadReq MSHR misses +system.cpu.l2cache.ReadReq_miss_latency 14169000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.990408 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 413 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 12857000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.990408 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 413 # number of ReadReq MSHR misses system.cpu.l2cache.UpgradeReq_accesses 15 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 34400 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 31166.666667 # average UpgradeReq mshr miss latency @@ -351,68 +351,68 @@ system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 system.cpu.l2cache.UpgradeReq_mshr_misses 15 # number of UpgradeReq MSHR misses system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 0.010076 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 0.010050 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 465 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 34350.325380 # average overall miss latency -system.cpu.l2cache.demand_avg_mshr_miss_latency 31159.436009 # average overall mshr miss latency +system.cpu.l2cache.demand_accesses 466 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 34349.567100 # average overall miss latency +system.cpu.l2cache.demand_avg_mshr_miss_latency 31160.173160 # average overall mshr miss latency system.cpu.l2cache.demand_hits 4 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 15835500 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.991398 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 461 # number of demand (read+write) misses +system.cpu.l2cache.demand_miss_latency 15869500 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.991416 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 462 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 14364500 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.991398 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 461 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 14396000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.991416 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 462 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 465 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 34350.325380 # average overall miss latency -system.cpu.l2cache.overall_avg_mshr_miss_latency 31159.436009 # average overall mshr miss latency +system.cpu.l2cache.overall_accesses 466 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 34349.567100 # average overall miss latency +system.cpu.l2cache.overall_avg_mshr_miss_latency 31160.173160 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.l2cache.overall_hits 4 # number of overall hits -system.cpu.l2cache.overall_miss_latency 15835500 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.991398 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 461 # number of overall misses +system.cpu.l2cache.overall_miss_latency 15869500 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.991416 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 462 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 14364500 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.991398 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 461 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 14396000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.991416 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 462 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.l2cache.replacements 0 # number of replacements -system.cpu.l2cache.sampled_refs 397 # Sample count of references to valid blocks. +system.cpu.l2cache.sampled_refs 398 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 208.689672 # Cycle average of tags in use +system.cpu.l2cache.tagsinuse 209.158769 # Cycle average of tags in use system.cpu.l2cache.total_refs 4 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.l2cache.writebacks 0 # number of writebacks system.cpu.memDep0.conflictingLoads 5 # Number of conflicting loads. system.cpu.memDep0.conflictingStores 2 # Number of conflicting stores. -system.cpu.memDep0.insertedLoads 2783 # Number of loads inserted to the mem dependence unit. +system.cpu.memDep0.insertedLoads 2795 # Number of loads inserted to the mem dependence unit. system.cpu.memDep0.insertedStores 1158 # Number of stores inserted to the mem dependence unit. -system.cpu.numCycles 27764 # number of cpu cycles simulated +system.cpu.numCycles 27830 # number of cpu cycles simulated system.cpu.rename.RENAME:BlockCycles 20 # Number of cycles rename is blocking -system.cpu.rename.RENAME:CommittedMaps 3304 # Number of HB maps that are committed -system.cpu.rename.RENAME:IdleCycles 10242 # Number of cycles rename is idle +system.cpu.rename.RENAME:CommittedMaps 3323 # Number of HB maps that are committed +system.cpu.rename.RENAME:IdleCycles 10291 # Number of cycles rename is idle system.cpu.rename.RENAME:LSQFullEvents 16 # Number of times rename has blocked due to LSQ full -system.cpu.rename.RENAME:RenameLookups 15583 # Number of register rename lookups that rename has made -system.cpu.rename.RENAME:RenamedInsts 13384 # Number of instructions processed by rename -system.cpu.rename.RENAME:RenamedOperands 8214 # Number of destination operands rename has renamed -system.cpu.rename.RENAME:RunCycles 3446 # Number of cycles rename is running -system.cpu.rename.RENAME:SquashCycles 1052 # Number of cycles rename is squashing +system.cpu.rename.RENAME:RenameLookups 15666 # Number of register rename lookups that rename has made +system.cpu.rename.RENAME:RenamedInsts 13454 # Number of instructions processed by rename +system.cpu.rename.RENAME:RenamedOperands 8251 # Number of destination operands rename has renamed +system.cpu.rename.RENAME:RunCycles 3462 # Number of cycles rename is running +system.cpu.rename.RENAME:SquashCycles 1056 # Number of cycles rename is squashing system.cpu.rename.RENAME:UnblockCycles 29 # Number of cycles rename is unblocking -system.cpu.rename.RENAME:UndoneMaps 4910 # Number of HB maps that are undone due to squashing +system.cpu.rename.RENAME:UndoneMaps 4928 # Number of HB maps that are undone due to squashing system.cpu.rename.RENAME:serializeStallCycles 428 # count of cycles rename stalled for serializing inst system.cpu.rename.RENAME:serializingInsts 20 # count of serializing insts renamed system.cpu.rename.RENAME:skidInsts 125 # count of insts added to the skid buffer system.cpu.rename.RENAME:tempSerializingInsts 14 # count of temporary serializing insts renamed -system.cpu.timesIdled 249 # Number of times that the entire CPU went into an idle state and unscheduled itself +system.cpu.timesIdled 250 # Number of times that the entire CPU went into an idle state and unscheduled itself system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simerr b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simerr index 187d1a0ac..aece78b32 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simerr +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simerr @@ -1,23 +1,5 @@ ["-r", "tests/configs/../../src/mem/ruby/config/MI_example-homogeneous.rb", "-p", "1", "-m", "1", "-s", "1024"] print config: 1 -Creating new MessageBuffer for 0 0 -Creating new MessageBuffer for 0 1 -Creating new MessageBuffer for 0 2 -Creating new MessageBuffer for 0 3 -Creating new MessageBuffer for 0 4 -Creating new MessageBuffer for 0 5 -Creating new MessageBuffer for 1 0 -Creating new MessageBuffer for 1 1 -Creating new MessageBuffer for 1 2 -Creating new MessageBuffer for 1 3 -Creating new MessageBuffer for 1 4 -Creating new MessageBuffer for 1 5 -Creating new MessageBuffer for 2 0 -Creating new MessageBuffer for 2 1 -Creating new MessageBuffer for 2 2 -Creating new MessageBuffer for 2 3 -Creating new MessageBuffer for 2 4 -Creating new MessageBuffer for 2 5 warn: Sockets disabled, not accepting gdb connections For more information see: http://www.m5sim.org/warn/d946bea6 hack: be nice to actually delete the event here diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simout b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simout index a97b34ba7..7408d6fc9 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simout +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simout @@ -5,14 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Jul 6 2009 11:05:29 -M5 revision d3635cac686a 6289 default ruby_refs.diff qtip tip -M5 started Jul 6 2009 11:11:09 -M5 executing on maize +M5 compiled Oct 6 2009 20:51:47 +M5 revision 300266bf68ec+ 6674+ default tip +M5 started Oct 6 2009 20:51:48 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-atomic-ruby -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-atomic-ruby Global frequency set at 1000000000000 ticks per second - Debug: Adding to filter: 'q' (Queue) info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 2828000 because target called exit() +Exiting @ tick 2842500 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/stats.txt b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/stats.txt index 8b9ded108..94d67cedd 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/stats.txt @@ -1,13 +1,13 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 47334 # Simulator instruction rate (inst/s) -host_mem_usage 1362452 # Number of bytes of host memory used -host_seconds 0.12 # Real time elapsed on the host -host_tick_rate 23634419 # Simulator tick rate (ticks/s) +host_inst_rate 27672 # Simulator instruction rate (inst/s) +host_mem_usage 1265116 # Number of bytes of host memory used +host_seconds 0.21 # Real time elapsed on the host +host_tick_rate 13820616 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated +sim_insts 5685 # Number of instructions simulated sim_seconds 0.000003 # Number of seconds simulated -sim_ticks 2828000 # Number of ticks simulated +sim_ticks 2842500 # Number of ticks simulated system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits system.cpu.dtb.misses 0 # DTB misses @@ -28,9 +28,9 @@ system.cpu.itb.write_accesses 0 # DT system.cpu.itb.write_hits 0 # DTB write hits system.cpu.itb.write_misses 0 # DTB write misses system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 5657 # number of cpu cycles simulated -system.cpu.num_insts 5656 # Number of instructions executed -system.cpu.num_refs 2055 # Number of memory references +system.cpu.numCycles 5686 # number of cpu cycles simulated +system.cpu.num_insts 5685 # Number of instructions executed +system.cpu.num_refs 2058 # Number of memory references system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic/config.ini b/tests/quick/00.hello/ref/mips/linux/simple-atomic/config.ini index 5d677c743..296171530 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic/config.ini +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic/config.ini @@ -111,7 +111,7 @@ egid=100 env= errout=cerr euid=100 -executable=/dist/m5/regression/test-progs/hello/bin/mips/linux/hello +executable=tests/test-progs/hello/bin/mips/linux/hello gid=100 input=cin max_stack_size=67108864 diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic/simout b/tests/quick/00.hello/ref/mips/linux/simple-atomic/simout index b140ca5f4..77cc5d321 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic/simout +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic/simout @@ -5,13 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Apr 21 2009 18:01:16 -M5 revision e6dd09514462 6117 default qtip tip stats-update -M5 started Apr 21 2009 18:01:42 -M5 executing on zizzer +M5 compiled Sep 24 2009 12:19:09 +M5 revision 9bc3e4611009+ 6661+ default tip +M5 started Sep 24 2009 12:19:47 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-atomic -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-atomic Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 2828000 because target called exit() +Exiting @ tick 2842500 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic/stats.txt b/tests/quick/00.hello/ref/mips/linux/simple-atomic/stats.txt index 60efc35e1..d36fc469a 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic/stats.txt @@ -1,13 +1,13 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 525065 # Simulator instruction rate (inst/s) -host_mem_usage 193736 # Number of bytes of host memory used +host_inst_rate 588083 # Simulator instruction rate (inst/s) +host_mem_usage 149516 # Number of bytes of host memory used host_seconds 0.01 # Real time elapsed on the host -host_tick_rate 257090909 # Simulator tick rate (ticks/s) +host_tick_rate 285563593 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated +sim_insts 5685 # Number of instructions simulated sim_seconds 0.000003 # Number of seconds simulated -sim_ticks 2828000 # Number of ticks simulated +sim_ticks 2842500 # Number of ticks simulated system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits system.cpu.dtb.misses 0 # DTB misses @@ -28,9 +28,9 @@ system.cpu.itb.write_accesses 0 # DT system.cpu.itb.write_hits 0 # DTB write hits system.cpu.itb.write_misses 0 # DTB write misses system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 5657 # number of cpu cycles simulated -system.cpu.num_insts 5656 # Number of instructions executed -system.cpu.num_refs 2055 # Number of memory references +system.cpu.numCycles 5686 # number of cpu cycles simulated +system.cpu.num_insts 5685 # Number of instructions executed +system.cpu.num_refs 2058 # Number of memory references system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simerr b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simerr index 187d1a0ac..aece78b32 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simerr +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simerr @@ -1,23 +1,5 @@ ["-r", "tests/configs/../../src/mem/ruby/config/MI_example-homogeneous.rb", "-p", "1", "-m", "1", "-s", "1024"] print config: 1 -Creating new MessageBuffer for 0 0 -Creating new MessageBuffer for 0 1 -Creating new MessageBuffer for 0 2 -Creating new MessageBuffer for 0 3 -Creating new MessageBuffer for 0 4 -Creating new MessageBuffer for 0 5 -Creating new MessageBuffer for 1 0 -Creating new MessageBuffer for 1 1 -Creating new MessageBuffer for 1 2 -Creating new MessageBuffer for 1 3 -Creating new MessageBuffer for 1 4 -Creating new MessageBuffer for 1 5 -Creating new MessageBuffer for 2 0 -Creating new MessageBuffer for 2 1 -Creating new MessageBuffer for 2 2 -Creating new MessageBuffer for 2 3 -Creating new MessageBuffer for 2 4 -Creating new MessageBuffer for 2 5 warn: Sockets disabled, not accepting gdb connections For more information see: http://www.m5sim.org/warn/d946bea6 hack: be nice to actually delete the event here diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simout b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simout index 8519ea0e2..6c7350461 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simout +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simout @@ -5,14 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Jul 6 2009 11:05:29 -M5 revision d3635cac686a 6289 default ruby_refs.diff qtip tip -M5 started Jul 6 2009 11:11:09 -M5 executing on maize +M5 compiled Oct 6 2009 20:43:14 +M5 revision 300266bf68ec 6674 default tip +M5 started Oct 6 2009 20:47:38 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-timing-ruby -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-timing-ruby Global frequency set at 1000000000000 ticks per second - Debug: Adding to filter: 'q' (Queue) info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 23131000 because target called exit() +Exiting @ tick 23227000 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/stats.txt b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/stats.txt index 95f42aecd..15c68a6b0 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/stats.txt @@ -1,13 +1,13 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 8081 # Simulator instruction rate (inst/s) -host_mem_usage 1362552 # Number of bytes of host memory used -host_seconds 0.70 # Real time elapsed on the host -host_tick_rate 33041595 # Simulator tick rate (ticks/s) +host_inst_rate 3701 # Simulator instruction rate (inst/s) +host_mem_usage 1265204 # Number of bytes of host memory used +host_seconds 1.54 # Real time elapsed on the host +host_tick_rate 15119806 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated +sim_insts 5685 # Number of instructions simulated sim_seconds 0.000023 # Number of seconds simulated -sim_ticks 23131000 # Number of ticks simulated +sim_ticks 23227000 # Number of ticks simulated system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits system.cpu.dtb.misses 0 # DTB misses @@ -28,9 +28,9 @@ system.cpu.itb.write_accesses 0 # DT system.cpu.itb.write_hits 0 # DTB write hits system.cpu.itb.write_misses 0 # DTB write misses system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 46262 # number of cpu cycles simulated -system.cpu.num_insts 5656 # Number of instructions executed -system.cpu.num_refs 2055 # Number of memory references +system.cpu.numCycles 46454 # number of cpu cycles simulated +system.cpu.num_insts 5685 # Number of instructions executed +system.cpu.num_refs 2058 # Number of memory references system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing/config.ini b/tests/quick/00.hello/ref/mips/linux/simple-timing/config.ini index 9f3729e92..2edca998b 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing/config.ini +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing/config.ini @@ -211,7 +211,7 @@ egid=100 env= errout=cerr euid=100 -executable=/dist/m5/regression/test-progs/hello/bin/mips/linux/hello +executable=tests/test-progs/hello/bin/mips/linux/hello gid=100 input=cin max_stack_size=67108864 diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing/simout b/tests/quick/00.hello/ref/mips/linux/simple-timing/simout index 7d691a50e..15331f633 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing/simout +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing/simout @@ -5,13 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Apr 22 2009 06:58:36 -M5 revision ce26a627c841 6126 default qtip tip stats_no_compat.diff -M5 started Apr 22 2009 07:19:48 -M5 executing on maize +M5 compiled Sep 24 2009 12:19:09 +M5 revision 9bc3e4611009+ 6661+ default tip +M5 started Sep 24 2009 12:19:31 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-timing -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 32322000 because target called exit() +Exiting @ tick 32409000 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing/stats.txt b/tests/quick/00.hello/ref/mips/linux/simple-timing/stats.txt index 8e4a1aeed..3bfaf3540 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing/stats.txt @@ -1,22 +1,22 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 198393 # Simulator instruction rate (inst/s) -host_mem_usage 202876 # Number of bytes of host memory used -host_seconds 0.03 # Real time elapsed on the host -host_tick_rate 1123305762 # Simulator tick rate (ticks/s) +host_inst_rate 303832 # Simulator instruction rate (inst/s) +host_mem_usage 155376 # Number of bytes of host memory used +host_seconds 0.02 # Real time elapsed on the host +host_tick_rate 1703674499 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated +sim_insts 5685 # Number of instructions simulated sim_seconds 0.000032 # Number of seconds simulated -sim_ticks 32322000 # Number of ticks simulated -system.cpu.dcache.ReadReq_accesses 1130 # number of ReadReq accesses(hits+misses) +sim_ticks 32409000 # Number of ticks simulated +system.cpu.dcache.ReadReq_accesses 1133 # number of ReadReq accesses(hits+misses) system.cpu.dcache.ReadReq_avg_miss_latency 56000 # average ReadReq miss latency system.cpu.dcache.ReadReq_avg_mshr_miss_latency 53000 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 1048 # number of ReadReq hits +system.cpu.dcache.ReadReq_hits 1051 # number of ReadReq hits system.cpu.dcache.ReadReq_miss_latency 4592000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.072566 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_miss_rate 0.072374 # miss rate for ReadReq accesses system.cpu.dcache.ReadReq_misses 82 # number of ReadReq misses system.cpu.dcache.ReadReq_mshr_miss_latency 4346000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.072566 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_miss_rate 0.072374 # mshr miss rate for ReadReq accesses system.cpu.dcache.ReadReq_mshr_misses 82 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 924 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 56000 # average WriteReq miss latency @@ -30,45 +30,45 @@ system.cpu.dcache.WriteReq_mshr_miss_rate 0.069264 # m system.cpu.dcache.WriteReq_mshr_misses 64 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 14.560606 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 14.583333 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed -system.cpu.dcache.demand_accesses 2054 # number of demand (read+write) accesses +system.cpu.dcache.demand_accesses 2057 # number of demand (read+write) accesses system.cpu.dcache.demand_avg_miss_latency 56000 # average overall miss latency system.cpu.dcache.demand_avg_mshr_miss_latency 53000 # average overall mshr miss latency -system.cpu.dcache.demand_hits 1908 # number of demand (read+write) hits +system.cpu.dcache.demand_hits 1911 # number of demand (read+write) hits system.cpu.dcache.demand_miss_latency 8176000 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.071081 # miss rate for demand accesses +system.cpu.dcache.demand_miss_rate 0.070977 # miss rate for demand accesses system.cpu.dcache.demand_misses 146 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits system.cpu.dcache.demand_mshr_miss_latency 7738000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.071081 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_miss_rate 0.070977 # mshr miss rate for demand accesses system.cpu.dcache.demand_mshr_misses 146 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.dcache.overall_accesses 2054 # number of overall (read+write) accesses +system.cpu.dcache.overall_accesses 2057 # number of overall (read+write) accesses system.cpu.dcache.overall_avg_miss_latency 56000 # average overall miss latency system.cpu.dcache.overall_avg_mshr_miss_latency 53000 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 1908 # number of overall hits +system.cpu.dcache.overall_hits 1911 # number of overall hits system.cpu.dcache.overall_miss_latency 8176000 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.071081 # miss rate for overall accesses +system.cpu.dcache.overall_miss_rate 0.070977 # miss rate for overall accesses system.cpu.dcache.overall_misses 146 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits system.cpu.dcache.overall_mshr_miss_latency 7738000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.071081 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_miss_rate 0.070977 # mshr miss rate for overall accesses system.cpu.dcache.overall_mshr_misses 146 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.dcache.replacements 0 # number of replacements system.cpu.dcache.sampled_refs 132 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 83.826869 # Cycle average of tags in use -system.cpu.dcache.total_refs 1922 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 83.830110 # Cycle average of tags in use +system.cpu.dcache.total_refs 1925 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.dcache.writebacks 0 # number of writebacks system.cpu.dtb.accesses 0 # DTB accesses @@ -80,57 +80,57 @@ system.cpu.dtb.read_misses 0 # DT system.cpu.dtb.write_accesses 0 # DTB write accesses system.cpu.dtb.write_hits 0 # DTB write hits system.cpu.dtb.write_misses 0 # DTB write misses -system.cpu.icache.ReadReq_accesses 5658 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 55722.772277 # average ReadReq miss latency -system.cpu.icache.ReadReq_avg_mshr_miss_latency 52722.772277 # average ReadReq mshr miss latency -system.cpu.icache.ReadReq_hits 5355 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 16884000 # number of ReadReq miss cycles -system.cpu.icache.ReadReq_miss_rate 0.053552 # miss rate for ReadReq accesses -system.cpu.icache.ReadReq_misses 303 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_miss_latency 15975000 # number of ReadReq MSHR miss cycles -system.cpu.icache.ReadReq_mshr_miss_rate 0.053552 # mshr miss rate for ReadReq accesses -system.cpu.icache.ReadReq_mshr_misses 303 # number of ReadReq MSHR misses +system.cpu.icache.ReadReq_accesses 5687 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 55723.684211 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 52723.684211 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_hits 5383 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 16940000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.053455 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 304 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_miss_latency 16028000 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_rate 0.053455 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_misses 304 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.icache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.icache.avg_refs 17.673267 # Average number of references to valid blocks. +system.cpu.icache.avg_refs 17.707237 # Average number of references to valid blocks. system.cpu.icache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed -system.cpu.icache.demand_accesses 5658 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 55722.772277 # average overall miss latency -system.cpu.icache.demand_avg_mshr_miss_latency 52722.772277 # average overall mshr miss latency -system.cpu.icache.demand_hits 5355 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 16884000 # number of demand (read+write) miss cycles -system.cpu.icache.demand_miss_rate 0.053552 # miss rate for demand accesses -system.cpu.icache.demand_misses 303 # number of demand (read+write) misses +system.cpu.icache.demand_accesses 5687 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 55723.684211 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 52723.684211 # average overall mshr miss latency +system.cpu.icache.demand_hits 5383 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 16940000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.053455 # miss rate for demand accesses +system.cpu.icache.demand_misses 304 # number of demand (read+write) misses system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.icache.demand_mshr_miss_latency 15975000 # number of demand (read+write) MSHR miss cycles -system.cpu.icache.demand_mshr_miss_rate 0.053552 # mshr miss rate for demand accesses -system.cpu.icache.demand_mshr_misses 303 # number of demand (read+write) MSHR misses +system.cpu.icache.demand_mshr_miss_latency 16028000 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_rate 0.053455 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_misses 304 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.icache.overall_accesses 5658 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 55722.772277 # average overall miss latency -system.cpu.icache.overall_avg_mshr_miss_latency 52722.772277 # average overall mshr miss latency +system.cpu.icache.overall_accesses 5687 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 55723.684211 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 52723.684211 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.icache.overall_hits 5355 # number of overall hits -system.cpu.icache.overall_miss_latency 16884000 # number of overall miss cycles -system.cpu.icache.overall_miss_rate 0.053552 # miss rate for overall accesses -system.cpu.icache.overall_misses 303 # number of overall misses +system.cpu.icache.overall_hits 5383 # number of overall hits +system.cpu.icache.overall_miss_latency 16940000 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.053455 # miss rate for overall accesses +system.cpu.icache.overall_misses 304 # number of overall misses system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.icache.overall_mshr_miss_latency 15975000 # number of overall MSHR miss cycles -system.cpu.icache.overall_mshr_miss_rate 0.053552 # mshr miss rate for overall accesses -system.cpu.icache.overall_mshr_misses 303 # number of overall MSHR misses +system.cpu.icache.overall_mshr_miss_latency 16028000 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_rate 0.053455 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_misses 304 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.icache.replacements 13 # number of replacements -system.cpu.icache.sampled_refs 303 # Sample count of references to valid blocks. +system.cpu.icache.sampled_refs 304 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 134.976151 # Cycle average of tags in use -system.cpu.icache.total_refs 5355 # Total number of references to valid blocks. +system.cpu.icache.tagsinuse 135.394401 # Cycle average of tags in use +system.cpu.icache.total_refs 5383 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles @@ -152,16 +152,16 @@ system.cpu.l2cache.ReadExReq_misses 50 # nu system.cpu.l2cache.ReadExReq_mshr_miss_latency 2000000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses system.cpu.l2cache.ReadExReq_mshr_misses 50 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 385 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_accesses 386 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency system.cpu.l2cache.ReadReq_hits 2 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 19916000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.994805 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 383 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 15320000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.994805 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 383 # number of ReadReq MSHR misses +system.cpu.l2cache.ReadReq_miss_latency 19968000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.994819 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 384 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 15360000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.994819 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 384 # number of ReadReq MSHR misses system.cpu.l2cache.UpgradeReq_accesses 14 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 52000 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency @@ -173,51 +173,51 @@ system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 system.cpu.l2cache.UpgradeReq_mshr_misses 14 # number of UpgradeReq MSHR misses system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 0.005420 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 0.005405 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 435 # number of demand (read+write) accesses +system.cpu.l2cache.demand_accesses 436 # number of demand (read+write) accesses system.cpu.l2cache.demand_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.demand_hits 2 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 22516000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.995402 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 433 # number of demand (read+write) misses +system.cpu.l2cache.demand_miss_latency 22568000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.995413 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 434 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 17320000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.995402 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 433 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 17360000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.995413 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 434 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 435 # number of overall (read+write) accesses +system.cpu.l2cache.overall_accesses 436 # number of overall (read+write) accesses system.cpu.l2cache.overall_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.l2cache.overall_hits 2 # number of overall hits -system.cpu.l2cache.overall_miss_latency 22516000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.995402 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 433 # number of overall misses +system.cpu.l2cache.overall_miss_latency 22568000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.995413 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 434 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 17320000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.995402 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 433 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 17360000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.995413 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 434 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.l2cache.replacements 0 # number of replacements -system.cpu.l2cache.sampled_refs 369 # Sample count of references to valid blocks. +system.cpu.l2cache.sampled_refs 370 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 181.998644 # Cycle average of tags in use +system.cpu.l2cache.tagsinuse 182.412916 # Cycle average of tags in use system.cpu.l2cache.total_refs 2 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.l2cache.writebacks 0 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 64644 # number of cpu cycles simulated -system.cpu.num_insts 5656 # Number of instructions executed -system.cpu.num_refs 2055 # Number of memory references +system.cpu.numCycles 64818 # number of cpu cycles simulated +system.cpu.num_insts 5685 # Number of instructions executed +system.cpu.num_refs 2058 # Number of memory references system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/power/linux/o3-timing/config.ini b/tests/quick/00.hello/ref/power/linux/o3-timing/config.ini new file mode 100644 index 000000000..6b0ea33cd --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/o3-timing/config.ini @@ -0,0 +1,389 @@ +[root] +type=Root +children=system +dummy=0 + +[system] +type=System +children=cpu membus physmem +mem_mode=atomic +physmem=system.physmem + +[system.cpu] +type=DerivO3CPU +children=dcache dtb fuPool icache itb l2cache toL2Bus tracer workload +BTBEntries=4096 +BTBTagSize=16 +LFSTSize=1024 +LQEntries=32 +RASSize=16 +SQEntries=32 +SSITSize=1024 +UnifiedTLB=true +activity=0 +backComSize=5 +cachePorts=200 +checker=Null +choiceCtrBits=2 +choicePredictorSize=8192 +clock=500 +commitToDecodeDelay=1 +commitToFetchDelay=1 +commitToIEWDelay=1 +commitToRenameDelay=1 +commitWidth=8 +cpu_id=0 +decodeToFetchDelay=1 +decodeToRenameDelay=1 +decodeWidth=8 +defer_registration=false +dispatchWidth=8 +do_checkpoint_insts=true +do_statistics_insts=true +dtb=system.cpu.dtb +fetchToDecodeDelay=1 +fetchTrapLatency=1 +fetchWidth=8 +forwardComSize=5 +fuPool=system.cpu.fuPool +function_trace=false +function_trace_start=0 +globalCtrBits=2 +globalHistoryBits=13 +globalPredictorSize=8192 +iewToCommitDelay=1 +iewToDecodeDelay=1 +iewToFetchDelay=1 +iewToRenameDelay=1 +instShiftAmt=2 +issueToExecuteDelay=1 +issueWidth=8 +itb=system.cpu.itb +localCtrBits=2 +localHistoryBits=11 +localHistoryTableSize=2048 +localPredictorSize=2048 +max_insts_all_threads=0 +max_insts_any_thread=0 +max_loads_all_threads=0 +max_loads_any_thread=0 +numIQEntries=64 +numPhysFloatRegs=256 +numPhysIntRegs=256 +numROBEntries=192 +numRobs=1 +numThreads=1 +phase=0 +predType=tournament +progress_interval=0 +renameToDecodeDelay=1 +renameToFetchDelay=1 +renameToIEWDelay=2 +renameToROBDelay=1 +renameWidth=8 +smtCommitPolicy=RoundRobin +smtFetchPolicy=SingleThread +smtIQPolicy=Partitioned +smtIQThreshold=100 +smtLSQPolicy=Partitioned +smtLSQThreshold=100 +smtNumFetchingThreads=1 +smtROBPolicy=Partitioned +smtROBThreshold=100 +squashWidth=8 +system=system +tracer=system.cpu.tracer +trapLatency=13 +wbDepth=1 +wbWidth=8 +workload=system.cpu.workload +dcache_port=system.cpu.dcache.cpu_side +icache_port=system.cpu.icache.cpu_side + +[system.cpu.dcache] +type=BaseCache +addr_range=0:18446744073709551615 +assoc=2 +block_size=64 +forward_snoops=true +hash_delay=1 +latency=1000 +max_miss_count=0 +mshrs=10 +prefetch_data_accesses_only=false +prefetch_degree=1 +prefetch_latency=10000 +prefetch_on_access=false +prefetch_past_page=false +prefetch_policy=none +prefetch_serial_squash=false +prefetch_use_cpu_id=true +prefetcher_size=100 +prioritizeRequests=false +repl=Null +size=262144 +subblock_size=0 +tgts_per_mshr=20 +trace_addr=0 +two_queue=false +write_buffers=8 +cpu_side=system.cpu.dcache_port +mem_side=system.cpu.toL2Bus.port[1] + +[system.cpu.dtb] +type=PowerTLB +size=64 + +[system.cpu.fuPool] +type=FUPool +children=FUList0 FUList1 FUList2 FUList3 FUList4 FUList5 FUList6 FUList7 +FUList=system.cpu.fuPool.FUList0 system.cpu.fuPool.FUList1 system.cpu.fuPool.FUList2 system.cpu.fuPool.FUList3 system.cpu.fuPool.FUList4 system.cpu.fuPool.FUList5 system.cpu.fuPool.FUList6 system.cpu.fuPool.FUList7 + +[system.cpu.fuPool.FUList0] +type=FUDesc +children=opList +count=6 +opList=system.cpu.fuPool.FUList0.opList + +[system.cpu.fuPool.FUList0.opList] +type=OpDesc +issueLat=1 +opClass=IntAlu +opLat=1 + +[system.cpu.fuPool.FUList1] +type=FUDesc +children=opList0 opList1 +count=2 +opList=system.cpu.fuPool.FUList1.opList0 system.cpu.fuPool.FUList1.opList1 + +[system.cpu.fuPool.FUList1.opList0] +type=OpDesc +issueLat=1 +opClass=IntMult +opLat=3 + +[system.cpu.fuPool.FUList1.opList1] +type=OpDesc +issueLat=19 +opClass=IntDiv +opLat=20 + +[system.cpu.fuPool.FUList2] +type=FUDesc +children=opList0 opList1 opList2 +count=4 +opList=system.cpu.fuPool.FUList2.opList0 system.cpu.fuPool.FUList2.opList1 system.cpu.fuPool.FUList2.opList2 + +[system.cpu.fuPool.FUList2.opList0] +type=OpDesc +issueLat=1 +opClass=FloatAdd +opLat=2 + +[system.cpu.fuPool.FUList2.opList1] +type=OpDesc +issueLat=1 +opClass=FloatCmp +opLat=2 + +[system.cpu.fuPool.FUList2.opList2] +type=OpDesc +issueLat=1 +opClass=FloatCvt +opLat=2 + +[system.cpu.fuPool.FUList3] +type=FUDesc +children=opList0 opList1 opList2 +count=2 +opList=system.cpu.fuPool.FUList3.opList0 system.cpu.fuPool.FUList3.opList1 system.cpu.fuPool.FUList3.opList2 + +[system.cpu.fuPool.FUList3.opList0] +type=OpDesc +issueLat=1 +opClass=FloatMult +opLat=4 + +[system.cpu.fuPool.FUList3.opList1] +type=OpDesc +issueLat=12 +opClass=FloatDiv +opLat=12 + +[system.cpu.fuPool.FUList3.opList2] +type=OpDesc +issueLat=24 +opClass=FloatSqrt +opLat=24 + +[system.cpu.fuPool.FUList4] +type=FUDesc +children=opList +count=0 +opList=system.cpu.fuPool.FUList4.opList + +[system.cpu.fuPool.FUList4.opList] +type=OpDesc +issueLat=1 +opClass=MemRead +opLat=1 + +[system.cpu.fuPool.FUList5] +type=FUDesc +children=opList +count=0 +opList=system.cpu.fuPool.FUList5.opList + +[system.cpu.fuPool.FUList5.opList] +type=OpDesc +issueLat=1 +opClass=MemWrite +opLat=1 + +[system.cpu.fuPool.FUList6] +type=FUDesc +children=opList0 opList1 +count=4 +opList=system.cpu.fuPool.FUList6.opList0 system.cpu.fuPool.FUList6.opList1 + +[system.cpu.fuPool.FUList6.opList0] +type=OpDesc +issueLat=1 +opClass=MemRead +opLat=1 + +[system.cpu.fuPool.FUList6.opList1] +type=OpDesc +issueLat=1 +opClass=MemWrite +opLat=1 + +[system.cpu.fuPool.FUList7] +type=FUDesc +children=opList +count=1 +opList=system.cpu.fuPool.FUList7.opList + +[system.cpu.fuPool.FUList7.opList] +type=OpDesc +issueLat=3 +opClass=IprAccess +opLat=3 + +[system.cpu.icache] +type=BaseCache +addr_range=0:18446744073709551615 +assoc=2 +block_size=64 +forward_snoops=true +hash_delay=1 +latency=1000 +max_miss_count=0 +mshrs=10 +prefetch_data_accesses_only=false +prefetch_degree=1 +prefetch_latency=10000 +prefetch_on_access=false +prefetch_past_page=false +prefetch_policy=none +prefetch_serial_squash=false +prefetch_use_cpu_id=true +prefetcher_size=100 +prioritizeRequests=false +repl=Null +size=131072 +subblock_size=0 +tgts_per_mshr=20 +trace_addr=0 +two_queue=false +write_buffers=8 +cpu_side=system.cpu.icache_port +mem_side=system.cpu.toL2Bus.port[0] + +[system.cpu.itb] +type=PowerTLB +size=64 + +[system.cpu.l2cache] +type=BaseCache +addr_range=0:18446744073709551615 +assoc=2 +block_size=64 +forward_snoops=true +hash_delay=1 +latency=1000 +max_miss_count=0 +mshrs=10 +prefetch_data_accesses_only=false +prefetch_degree=1 +prefetch_latency=10000 +prefetch_on_access=false +prefetch_past_page=false +prefetch_policy=none +prefetch_serial_squash=false +prefetch_use_cpu_id=true +prefetcher_size=100 +prioritizeRequests=false +repl=Null +size=2097152 +subblock_size=0 +tgts_per_mshr=5 +trace_addr=0 +two_queue=false +write_buffers=8 +cpu_side=system.cpu.toL2Bus.port[2] +mem_side=system.membus.port[1] + +[system.cpu.toL2Bus] +type=Bus +block_size=64 +bus_id=0 +clock=1000 +header_cycles=1 +responder_set=false +width=64 +port=system.cpu.icache.mem_side system.cpu.dcache.mem_side system.cpu.l2cache.cpu_side + +[system.cpu.tracer] +type=ExeTracer + +[system.cpu.workload] +type=LiveProcess +cmd=hello +cwd= +egid=100 +env= +errout=cerr +euid=100 +executable=tests/test-progs/hello/bin/power/linux/hello +gid=100 +input=cin +max_stack_size=67108864 +output=cout +pid=100 +ppid=99 +simpoint=0 +system=system +uid=100 + +[system.membus] +type=Bus +block_size=64 +bus_id=0 +clock=1000 +header_cycles=1 +responder_set=false +width=64 +port=system.physmem.port[0] system.cpu.l2cache.mem_side + +[system.physmem] +type=PhysicalMemory +file= +latency=30000 +latency_var=0 +null=false +range=0:134217727 +zero=false +port=system.membus.port[0] + diff --git a/tests/quick/00.hello/ref/power/linux/o3-timing/simerr b/tests/quick/00.hello/ref/power/linux/o3-timing/simerr new file mode 100755 index 000000000..a2692a6c9 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/o3-timing/simerr @@ -0,0 +1,5 @@ +warn: Sockets disabled, not accepting gdb connections +For more information see: http://www.m5sim.org/warn/d946bea6 +warn: allowing mmap of file @ fd 4294967295. This will break if not /dev/zero. +For more information see: http://www.m5sim.org/warn/3a2134f6 +hack: be nice to actually delete the event here diff --git a/tests/quick/00.hello/ref/power/linux/o3-timing/simout b/tests/quick/00.hello/ref/power/linux/o3-timing/simout new file mode 100755 index 000000000..bc2c673ec --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/o3-timing/simout @@ -0,0 +1,16 @@ +M5 Simulator System + +Copyright (c) 2001-2008 +The Regents of The University of Michigan +All Rights Reserved + + +M5 compiled Oct 15 2009 15:43:13 +M5 revision b43c2c69a460 6694 default hello-world-outputs.patch qtip tip +M5 started Oct 15 2009 15:49:09 +M5 executing on frontend01 +command line: build/POWER_SE/m5.fast -d build/POWER_SE/tests/fast/quick/00.hello/power/linux/o3-timing -re tests/run.py build/POWER_SE/tests/fast/quick/00.hello/power/linux/o3-timing +Global frequency set at 1000000000000 ticks per second +info: Entering event queue @ 0. Starting simulation... +Hello world! +Exiting @ tick 11960500 because target called exit() diff --git a/tests/quick/00.hello/ref/power/linux/o3-timing/stats.txt b/tests/quick/00.hello/ref/power/linux/o3-timing/stats.txt new file mode 100644 index 000000000..59c9aa334 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/o3-timing/stats.txt @@ -0,0 +1,421 @@ + +---------- Begin Simulation Statistics ---------- +host_inst_rate 103409 # Simulator instruction rate (inst/s) +host_mem_usage 271924 # Number of bytes of host memory used +host_seconds 0.06 # Real time elapsed on the host +host_tick_rate 212174700 # Simulator tick rate (ticks/s) +sim_freq 1000000000000 # Frequency of simulated ticks +sim_insts 5800 # Number of instructions simulated +sim_seconds 0.000012 # Number of seconds simulated +sim_ticks 11960500 # Number of ticks simulated +system.cpu.BPredUnit.BTBCorrect 0 # Number of correct BTB predictions (this stat may not work properly. +system.cpu.BPredUnit.BTBHits 734 # Number of BTB hits +system.cpu.BPredUnit.BTBLookups 1942 # Number of BTB lookups +system.cpu.BPredUnit.RASInCorrect 31 # Number of incorrect RAS predictions. +system.cpu.BPredUnit.condIncorrect 389 # Number of conditional branches incorrect +system.cpu.BPredUnit.condPredicted 1971 # Number of conditional branches predicted +system.cpu.BPredUnit.lookups 2303 # Number of BP lookups +system.cpu.BPredUnit.usedRAS 188 # Number of times the RAS was used to get a target. +system.cpu.commit.COM:branches 1038 # Number of branches committed +system.cpu.commit.COM:bw_lim_events 51 # number cycles where commit BW limit reached +system.cpu.commit.COM:bw_limited 0 # number of insts not committed due to BW limits +system.cpu.commit.COM:committed_per_cycle::samples 10831 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::mean 0.535500 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::stdev 1.248160 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::underflows 0 0.00% 0.00% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::0-1 8265 76.31% 76.31% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::1-2 1142 10.54% 86.85% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::2-3 659 6.08% 92.94% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::3-4 268 2.47% 95.41% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::4-5 226 2.09% 97.50% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::5-6 118 1.09% 98.59% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::6-7 80 0.74% 99.33% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::7-8 22 0.20% 99.53% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::8 51 0.47% 100.00% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::overflows 0 0.00% 100.00% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::min_value 0 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::max_value 8 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::total 10831 # Number of insts commited each cycle +system.cpu.commit.COM:count 5800 # Number of instructions committed +system.cpu.commit.COM:loads 962 # Number of loads committed +system.cpu.commit.COM:membars 7 # Number of memory barriers committed +system.cpu.commit.COM:refs 2008 # Number of memory references committed +system.cpu.commit.COM:swp_count 0 # Number of s/w prefetches committed +system.cpu.commit.branchMispredicts 243 # The number of times a branch was mispredicted +system.cpu.commit.commitCommittedInsts 5800 # The number of committed instructions +system.cpu.commit.commitNonSpecStalls 16 # The number of times commit has been forced to stall to communicate backwards +system.cpu.commit.commitSquashedInsts 3801 # The number of squashed insts skipped by commit +system.cpu.committedInsts 5800 # Number of Instructions Simulated +system.cpu.committedInsts_total 5800 # Number of Instructions Simulated +system.cpu.cpi 4.124483 # CPI: Cycles Per Instruction +system.cpu.cpi_total 4.124483 # CPI: Total CPI of All Threads +system.cpu.dcache.ReadReq_accesses 1436 # number of ReadReq accesses(hits+misses) +system.cpu.dcache.ReadReq_avg_miss_latency 33320.224719 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 34437.500000 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 1347 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 2965500 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.061978 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 89 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_hits 33 # number of ReadReq MSHR hits +system.cpu.dcache.ReadReq_mshr_miss_latency 1928500 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.038997 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 56 # number of ReadReq MSHR misses +system.cpu.dcache.WriteReq_accesses 1046 # number of WriteReq accesses(hits+misses) +system.cpu.dcache.WriteReq_avg_miss_latency 33497.150997 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 35861.538462 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 695 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 11757500 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.335564 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 351 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_hits 286 # number of WriteReq MSHR hits +system.cpu.dcache.WriteReq_mshr_miss_latency 2331000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.062141 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 65 # number of WriteReq MSHR misses +system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked +system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked +system.cpu.dcache.avg_refs 20.048077 # Average number of references to valid blocks. +system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked +system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked +system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked +system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked +system.cpu.dcache.cache_copies 0 # number of cache copies performed +system.cpu.dcache.demand_accesses 2482 # number of demand (read+write) accesses +system.cpu.dcache.demand_avg_miss_latency 33461.363636 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 35202.479339 # average overall mshr miss latency +system.cpu.dcache.demand_hits 2042 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 14723000 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.177276 # miss rate for demand accesses +system.cpu.dcache.demand_misses 440 # number of demand (read+write) misses +system.cpu.dcache.demand_mshr_hits 319 # number of demand (read+write) MSHR hits +system.cpu.dcache.demand_mshr_miss_latency 4259500 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.048751 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 121 # number of demand (read+write) MSHR misses +system.cpu.dcache.fast_writes 0 # number of fast writes performed +system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated +system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate +system.cpu.dcache.overall_accesses 2482 # number of overall (read+write) accesses +system.cpu.dcache.overall_avg_miss_latency 33461.363636 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 35202.479339 # average overall mshr miss latency +system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency +system.cpu.dcache.overall_hits 2042 # number of overall hits +system.cpu.dcache.overall_miss_latency 14723000 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.177276 # miss rate for overall accesses +system.cpu.dcache.overall_misses 440 # number of overall misses +system.cpu.dcache.overall_mshr_hits 319 # number of overall MSHR hits +system.cpu.dcache.overall_mshr_miss_latency 4259500 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.048751 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 121 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles +system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses +system.cpu.dcache.replacements 0 # number of replacements +system.cpu.dcache.sampled_refs 104 # Sample count of references to valid blocks. +system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions +system.cpu.dcache.tagsinuse 66.056188 # Cycle average of tags in use +system.cpu.dcache.total_refs 2085 # Total number of references to valid blocks. +system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. +system.cpu.dcache.writebacks 0 # number of writebacks +system.cpu.decode.DECODE:BlockedCycles 1201 # Number of cycles decode is blocked +system.cpu.decode.DECODE:BranchMispred 148 # Number of times decode detected a branch misprediction +system.cpu.decode.DECODE:BranchResolved 256 # Number of times decode resolved a branch +system.cpu.decode.DECODE:DecodedInsts 10901 # Number of instructions handled by decode +system.cpu.decode.DECODE:IdleCycles 7556 # Number of cycles decode is idle +system.cpu.decode.DECODE:RunCycles 2000 # Number of cycles decode is running +system.cpu.decode.DECODE:SquashCycles 615 # Number of cycles decode is squashing +system.cpu.decode.DECODE:SquashedInsts 416 # Number of squashed instructions handled by decode +system.cpu.decode.DECODE:UnblockCycles 74 # Number of cycles decode is unblocking +system.cpu.dtb.accesses 0 # DTB accesses +system.cpu.dtb.hits 0 # DTB hits +system.cpu.dtb.misses 0 # DTB misses +system.cpu.dtb.read_accesses 0 # DTB read accesses +system.cpu.dtb.read_hits 0 # DTB read hits +system.cpu.dtb.read_misses 0 # DTB read misses +system.cpu.dtb.write_accesses 0 # DTB write accesses +system.cpu.dtb.write_hits 0 # DTB write hits +system.cpu.dtb.write_misses 0 # DTB write misses +system.cpu.fetch.Branches 2303 # Number of branches that fetch encountered +system.cpu.fetch.CacheLines 1463 # Number of cache lines fetched +system.cpu.fetch.Cycles 3604 # Number of cycles fetch has run and was not squashing or blocked +system.cpu.fetch.IcacheSquashes 216 # Number of outstanding Icache misses that were squashed +system.cpu.fetch.Insts 12241 # Number of instructions fetch has processed +system.cpu.fetch.SquashCycles 411 # Number of cycles fetch has spent squashing +system.cpu.fetch.branchRate 0.096271 # Number of branch fetches per cycle +system.cpu.fetch.icacheStallCycles 1463 # Number of cycles fetch is stalled on an Icache miss +system.cpu.fetch.predictedBranches 922 # Number of branches that fetch has predicted taken +system.cpu.fetch.rate 0.511705 # Number of inst fetches per cycle +system.cpu.fetch.rateDist::samples 11446 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::mean 1.069457 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::stdev 2.458316 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::underflows 0 0.00% 0.00% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::0-1 9306 81.30% 81.30% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::1-2 148 1.29% 82.60% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::2-3 183 1.60% 84.20% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::3-4 143 1.25% 85.44% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::4-5 197 1.72% 87.17% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::5-6 135 1.18% 88.35% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::6-7 371 3.24% 91.59% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::7-8 95 0.83% 92.42% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::8 868 7.58% 100.00% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::overflows 0 0.00% 100.00% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::min_value 0 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::max_value 8 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::total 11446 # Number of instructions fetched each cycle (Total) +system.cpu.icache.ReadReq_accesses 1463 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 36616.094987 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 34771.212121 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_hits 1084 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 13877500 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.259057 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 379 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_hits 49 # number of ReadReq MSHR hits +system.cpu.icache.ReadReq_mshr_miss_latency 11474500 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_rate 0.225564 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_misses 330 # number of ReadReq MSHR misses +system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked +system.cpu.icache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked +system.cpu.icache.avg_refs 3.284848 # Average number of references to valid blocks. +system.cpu.icache.blocked::no_mshrs 0 # number of cycles access was blocked +system.cpu.icache.blocked::no_targets 0 # number of cycles access was blocked +system.cpu.icache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked +system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked +system.cpu.icache.cache_copies 0 # number of cache copies performed +system.cpu.icache.demand_accesses 1463 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 36616.094987 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 34771.212121 # average overall mshr miss latency +system.cpu.icache.demand_hits 1084 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 13877500 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.259057 # miss rate for demand accesses +system.cpu.icache.demand_misses 379 # number of demand (read+write) misses +system.cpu.icache.demand_mshr_hits 49 # number of demand (read+write) MSHR hits +system.cpu.icache.demand_mshr_miss_latency 11474500 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_rate 0.225564 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_misses 330 # number of demand (read+write) MSHR misses +system.cpu.icache.fast_writes 0 # number of fast writes performed +system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated +system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate +system.cpu.icache.overall_accesses 1463 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 36616.094987 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 34771.212121 # average overall mshr miss latency +system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency +system.cpu.icache.overall_hits 1084 # number of overall hits +system.cpu.icache.overall_miss_latency 13877500 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.259057 # miss rate for overall accesses +system.cpu.icache.overall_misses 379 # number of overall misses +system.cpu.icache.overall_mshr_hits 49 # number of overall MSHR hits +system.cpu.icache.overall_mshr_miss_latency 11474500 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_rate 0.225564 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_misses 330 # number of overall MSHR misses +system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles +system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses +system.cpu.icache.replacements 0 # number of replacements +system.cpu.icache.sampled_refs 330 # Sample count of references to valid blocks. +system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions +system.cpu.icache.tagsinuse 159.198376 # Cycle average of tags in use +system.cpu.icache.total_refs 1084 # Total number of references to valid blocks. +system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. +system.cpu.icache.writebacks 0 # number of writebacks +system.cpu.idleCycles 12476 # Total number of cycles that the CPU has spent unscheduled due to idling +system.cpu.iew.EXEC:branches 1260 # Number of branches executed +system.cpu.iew.EXEC:nop 0 # number of nop insts executed +system.cpu.iew.EXEC:rate 0.324680 # Inst execution rate +system.cpu.iew.EXEC:refs 2768 # number of memory reference insts executed +system.cpu.iew.EXEC:stores 1280 # Number of stores executed +system.cpu.iew.EXEC:swp 0 # number of swp insts executed +system.cpu.iew.WB:consumers 5977 # num instructions consuming a value +system.cpu.iew.WB:count 7563 # cumulative count of insts written-back +system.cpu.iew.WB:fanout 0.643801 # average fanout of values written-back +system.cpu.iew.WB:penalized 0 # number of instrctions required to write to 'other' IQ +system.cpu.iew.WB:penalized_rate 0 # fraction of instructions written-back that wrote to 'other' IQ +system.cpu.iew.WB:producers 3848 # num instructions producing a value +system.cpu.iew.WB:rate 0.316152 # insts written-back per cycle +system.cpu.iew.WB:sent 7622 # cumulative count of insts sent to commit +system.cpu.iew.branchMispredicts 279 # Number of branch mispredicts detected at execute +system.cpu.iew.iewBlockCycles 141 # Number of cycles IEW is blocking +system.cpu.iew.iewDispLoadInsts 1815 # Number of dispatched load instructions +system.cpu.iew.iewDispNonSpecInsts 14 # Number of dispatched non-speculative instructions +system.cpu.iew.iewDispSquashedInsts 102 # Number of squashed instructions skipped by dispatch +system.cpu.iew.iewDispStoreInsts 1394 # Number of dispatched store instructions +system.cpu.iew.iewDispatchedInsts 9586 # Number of instructions dispatched to IQ +system.cpu.iew.iewExecLoadInsts 1488 # Number of load instructions executed +system.cpu.iew.iewExecSquashedInsts 320 # Number of squashed instructions skipped in execute +system.cpu.iew.iewExecutedInsts 7767 # Number of executed instructions +system.cpu.iew.iewIQFullEvents 14 # Number of times the IQ has become full, causing a stall +system.cpu.iew.iewIdleCycles 0 # Number of cycles IEW is idle +system.cpu.iew.iewLSQFullEvents 0 # Number of times the LSQ has become full, causing a stall +system.cpu.iew.iewSquashCycles 615 # Number of cycles IEW is squashing +system.cpu.iew.iewUnblockCycles 20 # Number of cycles IEW is unblocking +system.cpu.iew.lsq.thread.0.blockedLoads 0 # Number of blocked loads due to partial load-store forwarding +system.cpu.iew.lsq.thread.0.cacheBlocked 0 # Number of times an access to memory failed due to the cache being blocked +system.cpu.iew.lsq.thread.0.forwLoads 28 # Number of loads that had data forwarded from stores +system.cpu.iew.lsq.thread.0.ignoredResponses 2 # Number of memory responses ignored because the instruction is squashed +system.cpu.iew.lsq.thread.0.invAddrLoads 0 # Number of loads ignored due to an invalid address +system.cpu.iew.lsq.thread.0.invAddrSwpfs 0 # Number of software prefetches ignored due to an invalid address +system.cpu.iew.lsq.thread.0.memOrderViolation 40 # Number of memory ordering violations +system.cpu.iew.lsq.thread.0.rescheduledLoads 1 # Number of loads that were rescheduled +system.cpu.iew.lsq.thread.0.squashedLoads 853 # Number of loads squashed +system.cpu.iew.lsq.thread.0.squashedStores 348 # Number of stores squashed +system.cpu.iew.memOrderViolationEvents 40 # Number of memory order violations +system.cpu.iew.predictedNotTakenIncorrect 215 # Number of branches that were predicted not taken incorrectly +system.cpu.iew.predictedTakenIncorrect 64 # Number of branches that were predicted taken incorrectly +system.cpu.ipc 0.242455 # IPC: Instructions Per Cycle +system.cpu.ipc_total 0.242455 # IPC: Total IPC of All Threads +system.cpu.iq.ISSUE:FU_type_0::No_OpClass 0 0.00% 0.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntAlu 5153 63.72% 63.72% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntMult 0 0.00% 63.72% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntDiv 0 0.00% 63.72% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatAdd 2 0.02% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatCmp 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatCvt 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatMult 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatDiv 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatSqrt 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::MemRead 1611 19.92% 83.67% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::MemWrite 1321 16.33% 100.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IprAccess 0 0.00% 100.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::InstPrefetch 0 0.00% 100.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::total 8087 # Type of FU issued +system.cpu.iq.ISSUE:fu_busy_cnt 141 # FU busy when requested +system.cpu.iq.ISSUE:fu_busy_rate 0.017435 # FU busy rate (busy events/executed inst) +system.cpu.iq.ISSUE:fu_full::No_OpClass 0 0.00% 0.00% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::IntAlu 11 7.80% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::IntMult 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::IntDiv 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatAdd 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatCmp 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatCvt 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatMult 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatDiv 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatSqrt 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::MemRead 67 47.52% 55.32% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::MemWrite 63 44.68% 100.00% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::IprAccess 0 0.00% 100.00% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::InstPrefetch 0 0.00% 100.00% # attempts to use FU when none available +system.cpu.iq.ISSUE:issued_per_cycle::samples 11446 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::mean 0.706535 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::stdev 1.384911 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::underflows 0 0.00% 0.00% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::0-1 8157 71.27% 71.27% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::1-2 1172 10.24% 81.50% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::2-3 822 7.18% 88.69% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::3-4 530 4.63% 93.32% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::4-5 377 3.29% 96.61% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::5-6 216 1.89% 98.50% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::6-7 120 1.05% 99.55% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::7-8 43 0.38% 99.92% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::8 9 0.08% 100.00% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::overflows 0 0.00% 100.00% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::min_value 0 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::max_value 8 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::total 11446 # Number of insts issued each cycle +system.cpu.iq.ISSUE:rate 0.338057 # Inst issue rate +system.cpu.iq.iqInstsAdded 9564 # Number of instructions added to the IQ (excludes non-spec) +system.cpu.iq.iqInstsIssued 8087 # Number of instructions issued +system.cpu.iq.iqNonSpecInstsAdded 22 # Number of non-speculative instructions added to the IQ +system.cpu.iq.iqSquashedInstsExamined 3408 # Number of squashed instructions iterated over during squash; mainly for profiling +system.cpu.iq.iqSquashedInstsIssued 7 # Number of squashed instructions issued +system.cpu.iq.iqSquashedNonSpecRemoved 6 # Number of squashed non-spec instructions that were removed +system.cpu.iq.iqSquashedOperandsExamined 3586 # Number of squashed operands that are examined and possibly removed from graph +system.cpu.itb.accesses 0 # DTB accesses +system.cpu.itb.hits 0 # DTB hits +system.cpu.itb.misses 0 # DTB misses +system.cpu.itb.read_accesses 0 # DTB read accesses +system.cpu.itb.read_hits 0 # DTB read hits +system.cpu.itb.read_misses 0 # DTB read misses +system.cpu.itb.write_accesses 0 # DTB write accesses +system.cpu.itb.write_hits 0 # DTB write hits +system.cpu.itb.write_misses 0 # DTB write misses +system.cpu.l2cache.ReadExReq_accesses 48 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_avg_miss_latency 34697.916667 # average ReadExReq miss latency +system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 31500 # average ReadExReq mshr miss latency +system.cpu.l2cache.ReadExReq_miss_latency 1665500 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses +system.cpu.l2cache.ReadExReq_misses 48 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 1512000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses +system.cpu.l2cache.ReadExReq_mshr_misses 48 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 386 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 34333.333333 # average ReadReq miss latency +system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 31156.084656 # average ReadReq mshr miss latency +system.cpu.l2cache.ReadReq_hits 8 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 12978000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.979275 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 378 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 11777000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.979275 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 378 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 17 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.UpgradeReq_avg_miss_latency 34235.294118 # average UpgradeReq miss latency +system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 31176.470588 # average UpgradeReq mshr miss latency +system.cpu.l2cache.UpgradeReq_miss_latency 582000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses +system.cpu.l2cache.UpgradeReq_misses 17 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 530000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses +system.cpu.l2cache.UpgradeReq_mshr_misses 17 # number of UpgradeReq MSHR misses +system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked +system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked +system.cpu.l2cache.avg_refs 0.022161 # Average number of references to valid blocks. +system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked +system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked +system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked +system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked +system.cpu.l2cache.cache_copies 0 # number of cache copies performed +system.cpu.l2cache.demand_accesses 434 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 34374.413146 # average overall miss latency +system.cpu.l2cache.demand_avg_mshr_miss_latency 31194.835681 # average overall mshr miss latency +system.cpu.l2cache.demand_hits 8 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 14643500 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.981567 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 426 # number of demand (read+write) misses +system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits +system.cpu.l2cache.demand_mshr_miss_latency 13289000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.981567 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 426 # number of demand (read+write) MSHR misses +system.cpu.l2cache.fast_writes 0 # number of fast writes performed +system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated +system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate +system.cpu.l2cache.overall_accesses 434 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 34374.413146 # average overall miss latency +system.cpu.l2cache.overall_avg_mshr_miss_latency 31194.835681 # average overall mshr miss latency +system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency +system.cpu.l2cache.overall_hits 8 # number of overall hits +system.cpu.l2cache.overall_miss_latency 14643500 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.981567 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 426 # number of overall misses +system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits +system.cpu.l2cache.overall_mshr_miss_latency 13289000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.981567 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 426 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles +system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses +system.cpu.l2cache.replacements 0 # number of replacements +system.cpu.l2cache.sampled_refs 361 # Sample count of references to valid blocks. +system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions +system.cpu.l2cache.tagsinuse 180.652204 # Cycle average of tags in use +system.cpu.l2cache.total_refs 8 # Total number of references to valid blocks. +system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. +system.cpu.l2cache.writebacks 0 # number of writebacks +system.cpu.memDep0.conflictingLoads 67 # Number of conflicting loads. +system.cpu.memDep0.conflictingStores 29 # Number of conflicting stores. +system.cpu.memDep0.insertedLoads 1815 # Number of loads inserted to the mem dependence unit. +system.cpu.memDep0.insertedStores 1394 # Number of stores inserted to the mem dependence unit. +system.cpu.numCycles 23922 # number of cpu cycles simulated +system.cpu.rename.RENAME:BlockCycles 356 # Number of cycles rename is blocking +system.cpu.rename.RENAME:CommittedMaps 5007 # Number of HB maps that are committed +system.cpu.rename.RENAME:IQFullEvents 7 # Number of times rename has blocked due to IQ full +system.cpu.rename.RENAME:IdleCycles 7745 # Number of cycles rename is idle +system.cpu.rename.RENAME:LSQFullEvents 222 # Number of times rename has blocked due to LSQ full +system.cpu.rename.RENAME:RenameLookups 17199 # Number of register rename lookups that rename has made +system.cpu.rename.RENAME:RenamedInsts 10376 # Number of instructions processed by rename +system.cpu.rename.RENAME:RenamedOperands 9321 # Number of destination operands rename has renamed +system.cpu.rename.RENAME:RunCycles 1877 # Number of cycles rename is running +system.cpu.rename.RENAME:SquashCycles 615 # Number of cycles rename is squashing +system.cpu.rename.RENAME:UnblockCycles 273 # Number of cycles rename is unblocking +system.cpu.rename.RENAME:UndoneMaps 4314 # Number of HB maps that are undone due to squashing +system.cpu.rename.RENAME:serializeStallCycles 580 # count of cycles rename stalled for serializing inst +system.cpu.rename.RENAME:serializingInsts 22 # count of serializing insts renamed +system.cpu.rename.RENAME:skidInsts 571 # count of insts added to the skid buffer +system.cpu.rename.RENAME:tempSerializingInsts 22 # count of temporary serializing insts renamed +system.cpu.timesIdled 231 # Number of times that the entire CPU went into an idle state and unscheduled itself +system.cpu.workload.PROG:num_syscalls 9 # Number of system calls + +---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/power/linux/simple-atomic/config.ini b/tests/quick/00.hello/ref/power/linux/simple-atomic/config.ini new file mode 100644 index 000000000..129c166c3 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/simple-atomic/config.ini @@ -0,0 +1,91 @@ +[root] +type=Root +children=system +dummy=0 + +[system] +type=System +children=cpu membus physmem +mem_mode=atomic +physmem=system.physmem + +[system.cpu] +type=AtomicSimpleCPU +children=dtb itb tracer workload +UnifiedTLB=true +checker=Null +clock=500 +cpu_id=0 +defer_registration=false +do_checkpoint_insts=true +do_statistics_insts=true +dtb=system.cpu.dtb +function_trace=false +function_trace_start=0 +itb=system.cpu.itb +max_insts_all_threads=0 +max_insts_any_thread=0 +max_loads_all_threads=0 +max_loads_any_thread=0 +numThreads=1 +phase=0 +progress_interval=0 +simulate_data_stalls=false +simulate_inst_stalls=false +system=system +tracer=system.cpu.tracer +width=1 +workload=system.cpu.workload +dcache_port=system.membus.port[2] +icache_port=system.membus.port[1] + +[system.cpu.dtb] +type=PowerTLB +size=64 + +[system.cpu.itb] +type=PowerTLB +size=64 + +[system.cpu.tracer] +type=ExeTracer + +[system.cpu.workload] +type=LiveProcess +cmd=hello +cwd= +egid=100 +env= +errout=cerr +euid=100 +executable=tests/test-progs/hello/bin/power/linux/hello +gid=100 +input=cin +max_stack_size=67108864 +output=cout +pid=100 +ppid=99 +simpoint=0 +system=system +uid=100 + +[system.membus] +type=Bus +block_size=64 +bus_id=0 +clock=1000 +header_cycles=1 +responder_set=false +width=64 +port=system.physmem.port[0] system.cpu.icache_port system.cpu.dcache_port + +[system.physmem] +type=PhysicalMemory +file= +latency=30000 +latency_var=0 +null=false +range=0:134217727 +zero=false +port=system.membus.port[0] + diff --git a/tests/quick/00.hello/ref/power/linux/simple-atomic/simerr b/tests/quick/00.hello/ref/power/linux/simple-atomic/simerr new file mode 100755 index 000000000..a2692a6c9 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/simple-atomic/simerr @@ -0,0 +1,5 @@ +warn: Sockets disabled, not accepting gdb connections +For more information see: http://www.m5sim.org/warn/d946bea6 +warn: allowing mmap of file @ fd 4294967295. This will break if not /dev/zero. +For more information see: http://www.m5sim.org/warn/3a2134f6 +hack: be nice to actually delete the event here diff --git a/tests/quick/00.hello/ref/power/linux/simple-atomic/simout b/tests/quick/00.hello/ref/power/linux/simple-atomic/simout new file mode 100755 index 000000000..410d89b19 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/simple-atomic/simout @@ -0,0 +1,16 @@ +M5 Simulator System + +Copyright (c) 2001-2008 +The Regents of The University of Michigan +All Rights Reserved + + +M5 compiled Oct 15 2009 15:43:13 +M5 revision b43c2c69a460 6694 default hello-world-outputs.patch qtip tip +M5 started Oct 15 2009 15:49:56 +M5 executing on frontend01 +command line: build/POWER_SE/m5.fast -d build/POWER_SE/tests/fast/quick/00.hello/power/linux/simple-atomic -re tests/run.py build/POWER_SE/tests/fast/quick/00.hello/power/linux/simple-atomic +Global frequency set at 1000000000000 ticks per second +info: Entering event queue @ 0. Starting simulation... +Hello world! +Exiting @ tick 2900000 because target called exit() diff --git a/tests/quick/00.hello/ref/power/linux/simple-atomic/stats.txt b/tests/quick/00.hello/ref/power/linux/simple-atomic/stats.txt new file mode 100644 index 000000000..325ee615a --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/simple-atomic/stats.txt @@ -0,0 +1,36 @@ + +---------- Begin Simulation Statistics ---------- +host_inst_rate 259216 # Simulator instruction rate (inst/s) +host_mem_usage 263696 # Number of bytes of host memory used +host_seconds 0.02 # Real time elapsed on the host +host_tick_rate 128114508 # Simulator tick rate (ticks/s) +sim_freq 1000000000000 # Frequency of simulated ticks +sim_insts 5801 # Number of instructions simulated +sim_seconds 0.000003 # Number of seconds simulated +sim_ticks 2900000 # Number of ticks simulated +system.cpu.dtb.accesses 0 # DTB accesses +system.cpu.dtb.hits 0 # DTB hits +system.cpu.dtb.misses 0 # DTB misses +system.cpu.dtb.read_accesses 0 # DTB read accesses +system.cpu.dtb.read_hits 0 # DTB read hits +system.cpu.dtb.read_misses 0 # DTB read misses +system.cpu.dtb.write_accesses 0 # DTB write accesses +system.cpu.dtb.write_hits 0 # DTB write hits +system.cpu.dtb.write_misses 0 # DTB write misses +system.cpu.idle_fraction 0 # Percentage of idle cycles +system.cpu.itb.accesses 0 # DTB accesses +system.cpu.itb.hits 0 # DTB hits +system.cpu.itb.misses 0 # DTB misses +system.cpu.itb.read_accesses 0 # DTB read accesses +system.cpu.itb.read_hits 0 # DTB read hits +system.cpu.itb.read_misses 0 # DTB read misses +system.cpu.itb.write_accesses 0 # DTB write accesses +system.cpu.itb.write_hits 0 # DTB write hits +system.cpu.itb.write_misses 0 # DTB write misses +system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles +system.cpu.numCycles 5801 # number of cpu cycles simulated +system.cpu.num_insts 5801 # Number of instructions executed +system.cpu.num_refs 2008 # Number of memory references +system.cpu.workload.PROG:num_syscalls 9 # Number of system calls + +---------- End Simulation Statistics ---------- diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/config.ini b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/config.ini index 99cec587f..b595ebc5e 100644 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/config.ini +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/config.ini @@ -160,8 +160,10 @@ latency=30000 latency_var=0 null=false num_cpus=8 +num_dmas=1 phase=0 -range=0:134217727 +ports_per_core=2 +range=0:1073741823 stats_file=ruby.stats zero=false port=system.membus.port[8] diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats index 9cdd67a6e..98cf9b30f 100644 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats @@ -12,7 +12,7 @@ RubySystem config: memory_size_bits: 30 DMA_Controller config: DMAController_0 version: 0 - buffer_size: 32 + buffer_size: 0 dma_sequencer: DMASequencer_0 number_of_TBEs: 256 recycle_latency: 10 @@ -20,18 +20,16 @@ DMA_Controller config: DMAController_0 transitions_per_cycle: 32 Directory_Controller config: DirectoryController_0 version: 0 - buffer_size: 32 + buffer_size: 0 directory_latency: 6 directory_name: DirectoryMemory_0 - dma_select_low_bit: 6 - dma_select_num_bits: 0 memory_controller_name: MemoryControl_0 number_of_TBEs: 256 recycle_latency: 10 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_0 version: 0 - buffer_size: 32 + buffer_size: 0 cache: l1u_0 cache_response_latency: 12 issue_latency: 2 @@ -41,7 +39,7 @@ L1Cache_Controller config: L1CacheController_0 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_1 version: 1 - buffer_size: 32 + buffer_size: 0 cache: l1u_1 cache_response_latency: 12 issue_latency: 2 @@ -51,7 +49,7 @@ L1Cache_Controller config: L1CacheController_1 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_2 version: 2 - buffer_size: 32 + buffer_size: 0 cache: l1u_2 cache_response_latency: 12 issue_latency: 2 @@ -61,7 +59,7 @@ L1Cache_Controller config: L1CacheController_2 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_3 version: 3 - buffer_size: 32 + buffer_size: 0 cache: l1u_3 cache_response_latency: 12 issue_latency: 2 @@ -71,7 +69,7 @@ L1Cache_Controller config: L1CacheController_3 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_4 version: 4 - buffer_size: 32 + buffer_size: 0 cache: l1u_4 cache_response_latency: 12 issue_latency: 2 @@ -81,7 +79,7 @@ L1Cache_Controller config: L1CacheController_4 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_5 version: 5 - buffer_size: 32 + buffer_size: 0 cache: l1u_5 cache_response_latency: 12 issue_latency: 2 @@ -91,7 +89,7 @@ L1Cache_Controller config: L1CacheController_5 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_6 version: 6 - buffer_size: 32 + buffer_size: 0 cache: l1u_6 cache_response_latency: 12 issue_latency: 2 @@ -101,7 +99,7 @@ L1Cache_Controller config: L1CacheController_6 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_7 version: 7 - buffer_size: 32 + buffer_size: 0 cache: l1u_7 cache_response_latency: 12 issue_latency: 2 @@ -111,92 +109,92 @@ L1Cache_Controller config: L1CacheController_7 transitions_per_cycle: 32 Cache config: l1u_0 controller: L1CacheController_0 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_1 controller: L1CacheController_1 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_2 controller: L1CacheController_2 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_3 controller: L1CacheController_3 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_4 controller: L1CacheController_4 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_5 controller: L1CacheController_5 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_6 controller: L1CacheController_6 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_7 controller: L1CacheController_7 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 DirectoryMemory Global Config: number of directory memories: 1 total memory size bytes: 1073741824 @@ -261,6 +259,10 @@ virtual_net_2: active, ordered virtual_net_3: inactive virtual_net_4: active, ordered virtual_net_5: active, ordered +virtual_net_6: inactive +virtual_net_7: inactive +virtual_net_8: inactive +virtual_net_9: inactive --- Begin Topology Print --- @@ -386,34 +388,34 @@ periodic_stats_period: 1000000 ================ End RubySystem Configuration Print ================ -Real time: Aug/11/2009 14:40:39 +Real time: Nov/18/2009 17:42:31 Profiler Stats -------------- -Elapsed_time_in_seconds: 3281 -Elapsed_time_in_minutes: 54.6833 -Elapsed_time_in_hours: 0.911389 -Elapsed_time_in_days: 0.0379745 +Elapsed_time_in_seconds: 3924 +Elapsed_time_in_minutes: 65.4 +Elapsed_time_in_hours: 1.09 +Elapsed_time_in_days: 0.0454167 -Virtual_time_in_seconds: 2972.6 -Virtual_time_in_minutes: 49.5433 -Virtual_time_in_hours: 0.825722 -Virtual_time_in_days: 0.0344051 +Virtual_time_in_seconds: 3921.96 +Virtual_time_in_minutes: 65.366 +Virtual_time_in_hours: 1.08943 +Virtual_time_in_days: 0.0453931 -Ruby_current_time: 31749699 +Ruby_current_time: 60455259 Ruby_start_time: 1 -Ruby_cycles: 31749698 +Ruby_cycles: 60455258 -mbytes_resident: 151.695 -mbytes_total: 151.898 -resident_ratio: 0.998688 +mbytes_resident: 151.762 +mbytes_total: 2381.61 +resident_ratio: 0.0637255 Total_misses: 0 total_misses: 0 [ 0 0 0 0 0 0 0 0 ] user_misses: 0 [ 0 0 0 0 0 0 0 0 ] supervisor_misses: 0 [ 0 0 0 0 0 0 0 0 ] -ruby_cycles_executed: 253997592 [ 31749699 31749699 31749699 31749699 31749699 31749699 31749699 31749699 ] +ruby_cycles_executed: 483642072 [ 60455259 60455259 60455259 60455259 60455259 60455259 60455259 60455259 ] transactions_started: 0 [ 0 0 0 0 0 0 0 0 ] transactions_ended: 0 [ 0 0 0 0 0 0 0 0 ] @@ -422,40 +424,40 @@ misses_per_transaction: 0 [ 0 0 0 0 0 0 0 0 ] Memory control MemoryControl_0: - memory_total_requests: 1384962 - memory_reads: 692528 - memory_writes: 692278 - memory_refreshes: 66146 - memory_total_request_delays: 423608080 - memory_delays_per_request: 305.863 - memory_delays_in_input_queue: 89056027 - memory_delays_behind_head_of_bank_queue: 254719145 - memory_delays_stalled_at_head_of_bank_queue: 79832908 - memory_stalls_for_bank_busy: 12075653 + memory_total_requests: 1497259 + memory_reads: 748631 + memory_writes: 748628 + memory_refreshes: 125949 + memory_total_request_delays: 10693878 + memory_delays_per_request: 7.1423 + memory_delays_in_input_queue: 3751785 + memory_delays_behind_head_of_bank_queue: 352863 + memory_delays_stalled_at_head_of_bank_queue: 6589230 + memory_stalls_for_bank_busy: 1322551 memory_stalls_for_random_busy: 0 - memory_stalls_for_anti_starvation: 24439291 - memory_stalls_for_arbitration: 15511923 - memory_stalls_for_bus: 20392505 + memory_stalls_for_anti_starvation: 8817 + memory_stalls_for_arbitration: 1317249 + memory_stalls_for_bus: 2228686 memory_stalls_for_tfaw: 0 - memory_stalls_for_read_write_turnaround: 5977752 - memory_stalls_for_read_read_turnaround: 1435784 - accesses_per_bank: 43368 43904 43706 43665 43508 43366 43384 43354 43590 43325 43301 43542 43264 43288 43218 43319 43219 43118 43315 43079 43237 43057 43107 43328 43242 42939 43225 42922 42943 43105 42885 43139 + memory_stalls_for_read_write_turnaround: 1350744 + memory_stalls_for_read_read_turnaround: 361183 + accesses_per_bank: 46780 46744 46842 46810 46806 46792 46736 46774 46868 46766 46784 46766 46757 46844 46764 46814 46814 46756 46796 46862 46782 46782 46770 46838 46780 46720 46750 46754 46840 46760 46788 46820 Busy Controller Counts: -L1Cache-0:0 L1Cache-1:0 L1Cache-2:1 L1Cache-3:0 L1Cache-4:0 L1Cache-5:1 L1Cache-6:0 L1Cache-7:1 +L1Cache-0:0 L1Cache-1:0 L1Cache-2:0 L1Cache-3:0 L1Cache-4:0 L1Cache-5:0 L1Cache-6:0 L1Cache-7:0 Directory-0:0 DMA-0:0 Busy Bank Count:0 -sequencer_requests_outstanding: [binsize: 1 max: 16 count: 746700 average: 11.7618 | standard deviation: 3.42904 | 0 1181 3107 5986 10114 16132 24128 33710 44657 55083 64138 69988 72441 71345 68309 64111 142270 ] +sequencer_requests_outstanding: [binsize: 1 max: 16 count: 749581 average: 15.7532 | standard deviation: 1.38784 | 0 475 726 892 999 1179 1408 1673 2066 2371 2666 3000 3297 3618 4065 5733 715413 ] All Non-Zero Cycle Demand Cache Accesses ---------------------------------------- -miss_latency: [binsize: 128 max: 21029 count: 746603 average: 3851.15 | standard deviation: 2350.44 | 21624 2037 3827 6735 8744 8494 7742 8727 10265 12114 13603 13888 12189 13262 16379 16977 16477 16214 17513 17457 16778 18444 19486 16712 16151 17669 18008 15987 15648 16356 15357 14058 14375 15390 13471 12148 12876 13458 11534 10630 11403 10961 9404 9160 10054 8956 7565 7967 8417 7419 6268 6810 6747 5598 5106 5611 5301 4304 4253 4461 4055 3421 3498 3461 3011 2534 2720 2664 2157 1912 2028 1911 1498 1441 1519 1315 1010 1086 1032 937 690 761 739 551 470 511 494 399 364 334 302 239 267 269 203 196 181 186 121 145 135 120 82 83 82 77 58 67 56 72 50 39 33 27 28 31 32 22 29 30 17 15 24 9 20 12 8 10 23 5 12 6 9 6 8 8 9 5 1 3 3 4 1 2 2 4 1 1 5 3 2 0 3 0 2 3 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] -miss_latency_2: [binsize: 128 max: 20539 count: 484935 average: 3851.68 | standard deviation: 2350.63 | 13904 1332 2494 4329 5749 5607 5063 5713 6766 7842 8848 9053 7883 8567 10537 10962 10638 10565 11405 11350 10806 12022 12693 10961 10540 11414 11604 10373 10192 10631 9965 9143 9337 9992 8755 7843 8355 8762 7428 6918 7435 7161 6157 5981 6496 5813 4849 5172 5493 4828 4049 4428 4328 3623 3316 3646 3442 2848 2798 2919 2659 2252 2225 2229 1937 1638 1781 1744 1433 1232 1308 1290 987 935 1010 866 664 696 662 603 432 499 463 350 290 332 316 246 240 209 206 142 174 178 129 124 108 122 77 99 92 77 54 48 58 48 32 42 37 50 33 28 24 17 20 23 25 15 22 20 14 10 13 5 16 9 5 5 14 3 7 3 2 4 4 5 6 4 1 3 3 3 0 1 2 3 0 1 4 1 0 0 3 0 2 2 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] -miss_latency_3: [binsize: 128 max: 21029 count: 261668 average: 3850.17 | standard deviation: 2350.1 | 7720 705 1333 2406 2995 2887 2679 3014 3499 4272 4755 4835 4306 4695 5842 6015 5839 5649 6108 6107 5972 6422 6793 5751 5611 6255 6404 5614 5456 5725 5392 4915 5038 5398 4716 4305 4521 4696 4106 3712 3968 3800 3247 3179 3558 3143 2716 2795 2924 2591 2219 2382 2419 1975 1790 1965 1859 1456 1455 1542 1396 1169 1273 1232 1074 896 939 920 724 680 720 621 511 506 509 449 346 390 370 334 258 262 276 201 180 179 178 153 124 125 96 97 93 91 74 72 73 64 44 46 43 43 28 35 24 29 26 25 19 22 17 11 9 10 8 8 7 7 7 10 3 5 11 4 4 3 3 5 9 2 5 3 7 2 4 3 3 1 0 0 0 1 1 1 0 1 1 0 1 2 2 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] +miss_latency: [binsize: 16 max: 2089 count: 749568 average: 1269.27 | standard deviation: 184.346 | 706 46 2 38 9 9 11 1 3 18 234 183 253 263 195 167 114 113 80 74 124 134 192 223 283 302 368 333 358 349 310 281 264 303 303 313 381 411 416 435 426 499 501 538 535 532 518 525 525 512 542 549 555 659 781 726 1112 1090 2204 3346 2562 5313 3505 7093 8407 5152 11332 6998 16292 21050 13121 29097 16803 34587 35992 18551 36492 19051 36733 37381 19033 37972 19036 35937 33738 16101 29532 14057 25324 22428 10173 18224 7932 13852 11409 4860 8441 3641 6175 4984 2172 3417 1391 2332 1751 697 1089 457 745 556 215 291 123 215 137 63 94 40 57 28 9 19 5 8 5 5 4 2 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] +miss_latency_2: [binsize: 16 max: 2059 count: 487448 average: 1269.28 | standard deviation: 183.834 | 432 31 2 21 7 7 8 1 1 8 150 118 169 171 119 101 77 70 54 51 73 78 128 142 175 205 218 217 223 230 208 191 173 202 219 188 238 265 274 281 284 338 317 343 345 351 350 322 342 355 341 355 368 421 494 491 737 709 1423 2160 1690 3504 2280 4639 5415 3375 7314 4535 10511 13782 8565 18932 10987 22355 23465 12092 23641 12545 24045 24209 12417 24627 12375 23363 21911 10475 19320 9131 16506 14610 6581 11831 5169 8995 7363 3196 5492 2339 3969 3226 1448 2182 890 1520 1118 446 700 293 484 359 146 173 86 141 81 42 61 28 39 21 7 13 3 7 2 3 3 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] +miss_latency_3: [binsize: 16 max: 2089 count: 262120 average: 1269.26 | standard deviation: 185.295 | 274 15 0 17 2 2 3 0 2 10 84 65 84 92 76 66 37 43 26 23 51 56 64 81 108 97 150 116 135 119 102 90 91 101 84 125 143 146 142 154 142 161 184 195 190 181 168 203 183 157 201 194 187 238 287 235 375 381 781 1186 872 1809 1225 2454 2992 1777 4018 2463 5781 7268 4556 10165 5816 12232 12527 6459 12851 6506 12688 13172 6616 13345 6661 12574 11827 5626 10212 4926 8818 7818 3592 6393 2763 4857 4046 1664 2949 1302 2206 1758 724 1235 501 812 633 251 389 164 261 197 69 118 37 74 56 21 33 12 18 7 2 6 2 1 3 2 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] All Non-Zero Cycle SW Prefetch Requests ------------------------------------ @@ -469,22 +471,26 @@ filter_action: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN Message Delayed Cycles ---------------------- -Total_delay_cycles: [binsize: 1 max: 34 count: 1493362 average: 0.00198612 | standard deviation: 0.174419 | 1493159 0 2 0 0 0 4 0 2 0 15 0 25 0 45 0 77 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] -Total_nonPF_delay_cycles: [binsize: 1 max: 34 count: 1493362 average: 0.00198612 | standard deviation: 0.174419 | 1493159 0 2 0 0 0 4 0 2 0 15 0 25 0 45 0 77 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] +Total_delay_cycles: [binsize: 1 max: 0 count: 1497256 average: 0 | standard deviation: 0 | 1497256 ] +Total_nonPF_delay_cycles: [binsize: 1 max: 0 count: 1497256 average: 0 | standard deviation: 0 | 1497256 ] virtual_network_0_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] - virtual_network_1_delay_cycles: [binsize: 1 max: 0 count: 746603 average: 0 | standard deviation: 0 | 746603 ] - virtual_network_2_delay_cycles: [binsize: 1 max: 34 count: 746759 average: 0.00397183 | standard deviation: 0.246637 | 746556 0 2 0 0 0 4 0 2 0 15 0 25 0 45 0 77 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] + virtual_network_1_delay_cycles: [binsize: 1 max: 0 count: 748630 average: 0 | standard deviation: 0 | 748630 ] + virtual_network_2_delay_cycles: [binsize: 1 max: 0 count: 748626 average: 0 | standard deviation: 0 | 748626 ] virtual_network_3_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] virtual_network_4_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] virtual_network_5_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] + virtual_network_6_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] + virtual_network_7_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] + virtual_network_8_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] + virtual_network_9_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] Resource Usage -------------- page_size: 4096 -user_time: 2896 -system_time: 75 -page_reclaims: 38173 -page_faults: 1923 +user_time: 3921 +system_time: 0 +page_reclaims: 40455 +page_faults: 3 swaps: 0 block_inputs: 0 block_outputs: 0 @@ -494,110 +500,74 @@ Network Stats switch_0_inlinks: 2 switch_0_outlinks: 2 -links_utilized_percent_switch_0: 0.0918637 - links_utilized_percent_switch_0_link_0: 0.0367355 bw: 640000 base_latency: 1 - links_utilized_percent_switch_0_link_1: 0.146992 bw: 160000 base_latency: 1 +links_utilized_percent_switch_0: 0.386974 + links_utilized_percent_switch_0_link_0: 0.15479 bw: 640000 base_latency: 1 + links_utilized_percent_switch_0_link_1: 0.619159 bw: 160000 base_latency: 1 - outgoing_messages_switch_0_link_0_Response_Data: 93305 6717960 [ 0 93305 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_0_Writeback_Control: 93328 746624 [ 0 0 93328 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_1_Control: 93321 746568 [ 93321 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_1_Data: 86792 6249024 [ 86792 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_1_Response_Data: 6549 471528 [ 0 6549 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_0_Response_Data: 748630 53901360 [ 0 748630 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_0_Writeback_Control: 748626 5989008 [ 0 0 748626 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_1_Control: 748631 5989048 [ 748631 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_1_Data: 748628 53901216 [ 748628 0 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_1_inlinks: 2 switch_1_outlinks: 2 -links_utilized_percent_switch_1: 0.0918631 - links_utilized_percent_switch_1_link_0: 0.0367386 bw: 640000 base_latency: 1 - links_utilized_percent_switch_1_link_1: 0.146988 bw: 160000 base_latency: 1 +links_utilized_percent_switch_1: 0 + links_utilized_percent_switch_1_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_1_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_1_link_0_Response_Data: 93314 6718608 [ 0 93314 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_0_Writeback_Control: 93325 746600 [ 0 0 93325 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_1_Control: 93321 746568 [ 93321 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_1_Data: 86443 6223896 [ 86443 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_1_Response_Data: 6895 496440 [ 0 6895 0 0 0 0 ] base_latency: 1 switch_2_inlinks: 2 switch_2_outlinks: 2 -links_utilized_percent_switch_2: 0.0918489 - links_utilized_percent_switch_2_link_0: 0.0367347 bw: 640000 base_latency: 1 - links_utilized_percent_switch_2_link_1: 0.146963 bw: 160000 base_latency: 1 +links_utilized_percent_switch_2: 0 + links_utilized_percent_switch_2_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_2_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_2_link_0_Response_Data: 93304 6717888 [ 0 93304 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_0_Writeback_Control: 93317 746536 [ 0 0 93317 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_1_Control: 93309 746472 [ 93309 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_1_Data: 86441 6223752 [ 86441 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_1_Response_Data: 6881 495432 [ 0 6881 0 0 0 0 ] base_latency: 1 switch_3_inlinks: 2 switch_3_outlinks: 2 -links_utilized_percent_switch_3: 0.0918764 - links_utilized_percent_switch_3_link_0: 0.0367424 bw: 640000 base_latency: 1 - links_utilized_percent_switch_3_link_1: 0.14701 bw: 160000 base_latency: 1 +links_utilized_percent_switch_3: 0 + links_utilized_percent_switch_3_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_3_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_3_link_0_Response_Data: 93323 6719256 [ 0 93323 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_0_Writeback_Control: 93340 746720 [ 0 0 93340 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_1_Control: 93330 746640 [ 93330 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_1_Data: 86471 6225912 [ 86471 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_1_Response_Data: 6882 495504 [ 0 6882 0 0 0 0 ] base_latency: 1 switch_4_inlinks: 2 switch_4_outlinks: 2 -links_utilized_percent_switch_4: 0.091891 - links_utilized_percent_switch_4_link_0: 0.0367495 bw: 640000 base_latency: 1 - links_utilized_percent_switch_4_link_1: 0.147032 bw: 160000 base_latency: 1 +links_utilized_percent_switch_4: 0 + links_utilized_percent_switch_4_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_4_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_4_link_0_Response_Data: 93342 6720624 [ 0 93342 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_0_Writeback_Control: 93350 746800 [ 0 0 93350 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_1_Control: 93353 746824 [ 93353 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_1_Data: 86738 6245136 [ 86738 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_1_Response_Data: 6628 477216 [ 0 6628 0 0 0 0 ] base_latency: 1 switch_5_inlinks: 2 switch_5_outlinks: 2 -links_utilized_percent_switch_5: 0.0918769 - links_utilized_percent_switch_5_link_0: 0.0367404 bw: 640000 base_latency: 1 - links_utilized_percent_switch_5_link_1: 0.147013 bw: 160000 base_latency: 1 +links_utilized_percent_switch_5: 0 + links_utilized_percent_switch_5_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_5_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_5_link_0_Response_Data: 93317 6718824 [ 0 93317 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_0_Writeback_Control: 93344 746752 [ 0 0 93344 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_1_Control: 93331 746648 [ 93331 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_1_Data: 86620 6236640 [ 86620 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_1_Response_Data: 6735 484920 [ 0 6735 0 0 0 0 ] base_latency: 1 switch_6_inlinks: 2 switch_6_outlinks: 2 -links_utilized_percent_switch_6: 0.0919038 - links_utilized_percent_switch_6_link_0: 0.0367512 bw: 640000 base_latency: 1 - links_utilized_percent_switch_6_link_1: 0.147057 bw: 160000 base_latency: 1 +links_utilized_percent_switch_6: 0 + links_utilized_percent_switch_6_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_6_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_6_link_0_Response_Data: 93344 6720768 [ 0 93344 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_0_Writeback_Control: 93375 747000 [ 0 0 93375 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_1_Control: 93353 746824 [ 93353 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_1_Data: 86552 6231744 [ 86552 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_1_Response_Data: 6831 491832 [ 0 6831 0 0 0 0 ] base_latency: 1 switch_7_inlinks: 2 switch_7_outlinks: 2 -links_utilized_percent_switch_7: 0.0919101 - links_utilized_percent_switch_7_link_0: 0.0367549 bw: 640000 base_latency: 1 - links_utilized_percent_switch_7_link_1: 0.147065 bw: 160000 base_latency: 1 +links_utilized_percent_switch_7: 0 + links_utilized_percent_switch_7_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_7_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_7_link_0_Response_Data: 93354 6721488 [ 0 93354 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_0_Writeback_Control: 93380 747040 [ 0 0 93380 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_1_Control: 93364 746912 [ 93364 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_1_Data: 86714 6243408 [ 86714 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_1_Response_Data: 6674 480528 [ 0 6674 0 0 0 0 ] base_latency: 1 switch_8_inlinks: 2 switch_8_outlinks: 2 -links_utilized_percent_switch_8: 0.687008 - links_utilized_percent_switch_8_link_0: 0.27487 bw: 640000 base_latency: 1 - links_utilized_percent_switch_8_link_1: 1.09915 bw: 160000 base_latency: 1 +links_utilized_percent_switch_8: 0.386975 + links_utilized_percent_switch_8_link_0: 0.15479 bw: 640000 base_latency: 1 + links_utilized_percent_switch_8_link_1: 0.61916 bw: 160000 base_latency: 1 - outgoing_messages_switch_8_link_0_Control: 746682 5973456 [ 746682 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_8_link_0_Data: 692771 49879512 [ 692771 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_8_link_1_Response_Data: 692528 49862016 [ 0 692528 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_8_link_1_Writeback_Control: 746759 5974072 [ 0 0 746759 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_0_Control: 748631 5989048 [ 748631 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_0_Data: 748628 53901216 [ 748628 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_1_Response_Data: 748630 53901360 [ 0 748630 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_1_Writeback_Control: 748626 5989008 [ 0 0 748626 0 0 0 0 0 0 0 ] base_latency: 1 switch_9_inlinks: 2 switch_9_outlinks: 2 @@ -608,148 +578,106 @@ links_utilized_percent_switch_9: 0 switch_10_inlinks: 10 switch_10_outlinks: 10 -links_utilized_percent_switch_10: 0.227527 - links_utilized_percent_switch_10_link_0: 0.146942 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_1: 0.146954 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_2: 0.146939 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_3: 0.146969 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_4: 0.146998 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_5: 0.146962 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_6: 0.147005 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_7: 0.14702 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_8: 1.09948 bw: 160000 base_latency: 1 +links_utilized_percent_switch_10: 0.123832 + links_utilized_percent_switch_10_link_0: 0.61916 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_1: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_2: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_3: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_4: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_5: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_6: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_7: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_8: 0.619159 bw: 160000 base_latency: 1 links_utilized_percent_switch_10_link_9: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_10_link_0_Response_Data: 93305 6717960 [ 0 93305 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_0_Writeback_Control: 93328 746624 [ 0 0 93328 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_1_Response_Data: 93314 6718608 [ 0 93314 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_1_Writeback_Control: 93325 746600 [ 0 0 93325 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_2_Response_Data: 93304 6717888 [ 0 93304 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_2_Writeback_Control: 93317 746536 [ 0 0 93317 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_3_Response_Data: 93323 6719256 [ 0 93323 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_3_Writeback_Control: 93340 746720 [ 0 0 93340 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_4_Response_Data: 93342 6720624 [ 0 93342 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_4_Writeback_Control: 93350 746800 [ 0 0 93350 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_5_Response_Data: 93317 6718824 [ 0 93317 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_5_Writeback_Control: 93344 746752 [ 0 0 93344 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_6_Response_Data: 93344 6720768 [ 0 93344 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_6_Writeback_Control: 93375 747000 [ 0 0 93375 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_7_Response_Data: 93354 6721488 [ 0 93354 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_7_Writeback_Control: 93380 747040 [ 0 0 93380 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_8_Control: 746682 5973456 [ 746682 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_8_Data: 692771 49879512 [ 692771 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_0_Response_Data: 748630 53901360 [ 0 748630 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_0_Writeback_Control: 748626 5989008 [ 0 0 748626 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_8_Control: 748631 5989048 [ 748631 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_8_Data: 748628 53901216 [ 748628 0 0 0 0 0 0 0 0 0 ] base_latency: 1 l1u_0 cache stats: - l1u_0_total_misses: 93321 - l1u_0_total_demand_misses: 93321 + l1u_0_total_misses: 748631 + l1u_0_total_demand_misses: 748631 l1u_0_total_prefetches: 0 l1u_0_total_sw_prefetches: 0 l1u_0_total_hw_prefetches: 0 l1u_0_misses_per_transaction: inf - l1u_0_request_type_LD: 65.0004% - l1u_0_request_type_ST: 34.9996% + l1u_0_request_type_LD: 65.0336% + l1u_0_request_type_ST: 34.9664% - l1u_0_access_mode_type_SupervisorMode: 93321 100% - l1u_0_request_size: [binsize: log2 max: 1 count: 93321 average: 1 | standard deviation: 0 | 0 93321 ] + l1u_0_access_mode_type_SupervisorMode: 748631 100% + l1u_0_request_size: [binsize: log2 max: 1 count: 748631 average: 1 | standard deviation: 0 | 0 748631 ] l1u_1 cache stats: - l1u_1_total_misses: 93321 - l1u_1_total_demand_misses: 93321 + l1u_1_total_misses: 0 + l1u_1_total_demand_misses: 0 l1u_1_total_prefetches: 0 l1u_1_total_sw_prefetches: 0 l1u_1_total_hw_prefetches: 0 - l1u_1_misses_per_transaction: inf + l1u_1_misses_per_transaction: nan - l1u_1_request_type_LD: 65.1536% - l1u_1_request_type_ST: 34.8464% - - l1u_1_access_mode_type_SupervisorMode: 93321 100% - l1u_1_request_size: [binsize: log2 max: 1 count: 93321 average: 1 | standard deviation: 0 | 0 93321 ] + l1u_1_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_2 cache stats: - l1u_2_total_misses: 93309 - l1u_2_total_demand_misses: 93309 + l1u_2_total_misses: 0 + l1u_2_total_demand_misses: 0 l1u_2_total_prefetches: 0 l1u_2_total_sw_prefetches: 0 l1u_2_total_hw_prefetches: 0 - l1u_2_misses_per_transaction: inf - - l1u_2_request_type_LD: 65.0002% - l1u_2_request_type_ST: 34.9998% + l1u_2_misses_per_transaction: nan - l1u_2_access_mode_type_SupervisorMode: 93309 100% - l1u_2_request_size: [binsize: log2 max: 1 count: 93309 average: 1 | standard deviation: 0 | 0 93309 ] + l1u_2_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_3 cache stats: - l1u_3_total_misses: 93330 - l1u_3_total_demand_misses: 93330 + l1u_3_total_misses: 0 + l1u_3_total_demand_misses: 0 l1u_3_total_prefetches: 0 l1u_3_total_sw_prefetches: 0 l1u_3_total_hw_prefetches: 0 - l1u_3_misses_per_transaction: inf - - l1u_3_request_type_LD: 64.663% - l1u_3_request_type_ST: 35.337% + l1u_3_misses_per_transaction: nan - l1u_3_access_mode_type_SupervisorMode: 93330 100% - l1u_3_request_size: [binsize: log2 max: 1 count: 93330 average: 1 | standard deviation: 0 | 0 93330 ] + l1u_3_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_4 cache stats: - l1u_4_total_misses: 93353 - l1u_4_total_demand_misses: 93353 + l1u_4_total_misses: 0 + l1u_4_total_demand_misses: 0 l1u_4_total_prefetches: 0 l1u_4_total_sw_prefetches: 0 l1u_4_total_hw_prefetches: 0 - l1u_4_misses_per_transaction: inf + l1u_4_misses_per_transaction: nan - l1u_4_request_type_LD: 65.2555% - l1u_4_request_type_ST: 34.7445% - - l1u_4_access_mode_type_SupervisorMode: 93353 100% - l1u_4_request_size: [binsize: log2 max: 1 count: 93353 average: 1 | standard deviation: 0 | 0 93353 ] + l1u_4_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_5 cache stats: - l1u_5_total_misses: 93331 - l1u_5_total_demand_misses: 93331 + l1u_5_total_misses: 0 + l1u_5_total_demand_misses: 0 l1u_5_total_prefetches: 0 l1u_5_total_sw_prefetches: 0 l1u_5_total_hw_prefetches: 0 - l1u_5_misses_per_transaction: inf - - l1u_5_request_type_LD: 64.7148% - l1u_5_request_type_ST: 35.2852% + l1u_5_misses_per_transaction: nan - l1u_5_access_mode_type_SupervisorMode: 93331 100% - l1u_5_request_size: [binsize: log2 max: 1 count: 93331 average: 1 | standard deviation: 0 | 0 93331 ] + l1u_5_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_6 cache stats: - l1u_6_total_misses: 93353 - l1u_6_total_demand_misses: 93353 + l1u_6_total_misses: 0 + l1u_6_total_demand_misses: 0 l1u_6_total_prefetches: 0 l1u_6_total_sw_prefetches: 0 l1u_6_total_hw_prefetches: 0 - l1u_6_misses_per_transaction: inf + l1u_6_misses_per_transaction: nan - l1u_6_request_type_LD: 64.916% - l1u_6_request_type_ST: 35.084% - - l1u_6_access_mode_type_SupervisorMode: 93353 100% - l1u_6_request_size: [binsize: log2 max: 1 count: 93353 average: 1 | standard deviation: 0 | 0 93353 ] + l1u_6_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_7 cache stats: - l1u_7_total_misses: 93364 - l1u_7_total_demand_misses: 93364 + l1u_7_total_misses: 0 + l1u_7_total_demand_misses: 0 l1u_7_total_prefetches: 0 l1u_7_total_sw_prefetches: 0 l1u_7_total_hw_prefetches: 0 - l1u_7_misses_per_transaction: inf - - l1u_7_request_type_LD: 64.9201% - l1u_7_request_type_ST: 35.0799% + l1u_7_misses_per_transaction: nan - l1u_7_access_mode_type_SupervisorMode: 93364 100% - l1u_7_request_size: [binsize: log2 max: 1 count: 93364 average: 1 | standard deviation: 0 | 0 93364 ] + l1u_7_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] --- DMA 0 --- - Event Counts - @@ -768,24 +696,24 @@ BUSY_WR Ack 0 <-- --- Directory 0 --- - Event Counts - -GETX 7453001 +GETX 748631 GETS 0 -PUTX 692359 -PUTX_NotOwner 411 +PUTX 748628 +PUTX_NotOwner 0 DMA_READ 0 DMA_WRITE 0 -Memory_Data 692528 -Memory_Ack 692273 +Memory_Data 748630 +Memory_Ack 748626 - Transitions - -I GETX 692603 +I GETX 748631 I PUTX_NotOwner 0 <-- I DMA_READ 0 <-- I DMA_WRITE 0 <-- -M GETX 54075 -M PUTX 692359 -M PUTX_NotOwner 411 +M GETX 0 <-- +M PUTX 748628 +M PUTX_NotOwner 0 <-- M DMA_READ 0 <-- M DMA_WRITE 0 <-- @@ -795,23 +723,27 @@ M_DRD PUTX 0 <-- M_DWR GETX 0 <-- M_DWR PUTX 0 <-- +M_DWRI GETX 0 <-- M_DWRI Memory_Ack 0 <-- -IM GETX 3217979 +M_DRDI GETX 0 <-- +M_DRDI Memory_Ack 0 <-- + +IM GETX 0 <-- IM GETS 0 <-- IM PUTX 0 <-- IM PUTX_NotOwner 0 <-- IM DMA_READ 0 <-- IM DMA_WRITE 0 <-- -IM Memory_Data 692528 +IM Memory_Data 748630 -MI GETX 3488344 +MI GETX 0 <-- MI GETS 0 <-- MI PUTX 0 <-- MI PUTX_NotOwner 0 <-- MI DMA_READ 0 <-- MI DMA_WRITE 0 <-- -MI Memory_Ack 692273 +MI Memory_Ack 748626 ID GETX 0 <-- ID GETS 0 <-- @@ -831,289 +763,289 @@ ID_W Memory_Ack 0 <-- --- L1Cache 0 --- - Event Counts - -Load 60659 +Load 487449 Ifetch 0 -Store 32662 -Data 93305 -Fwd_GETX 6549 +Store 262120 +Data 748630 +Fwd_GETX 0 Inv 0 -Replacement 93289 -Writeback_Ack 86728 -Writeback_Nack 51 +Replacement 748628 +Writeback_Ack 748626 +Writeback_Nack 0 - Transitions - -I Load 60659 +I Load 486862 I Ifetch 0 <-- -I Store 32662 +I Store 261769 I Inv 0 <-- -I Replacement 6497 +I Replacement 0 <-- -II Writeback_Nack 51 +II Writeback_Nack 0 <-- -M Load 0 <-- +M Load 587 M Ifetch 0 <-- -M Store 0 <-- -M Fwd_GETX 6498 +M Store 351 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86792 +M Replacement 748628 -MI Fwd_GETX 51 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86728 +MI Writeback_Ack 748626 -IS Data 60648 +IS Data 486861 -IM Data 32657 +IM Data 261769 --- L1Cache 1 --- - Event Counts - -Load 60802 +Load 0 Ifetch 0 -Store 32519 -Data 93314 -Fwd_GETX 6895 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93289 -Writeback_Ack 86383 -Writeback_Nack 47 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60802 +I Load 0 <-- I Ifetch 0 <-- -I Store 32519 +I Store 0 <-- I Inv 0 <-- -I Replacement 6846 +I Replacement 0 <-- -II Writeback_Nack 47 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6848 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86443 +M Replacement 0 <-- -MI Fwd_GETX 47 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86383 +MI Writeback_Ack 0 <-- -IS Data 60797 +IS Data 0 <-- -IM Data 32517 +IM Data 0 <-- --- L1Cache 2 --- - Event Counts - -Load 60651 +Load 0 Ifetch 0 -Store 32658 -Data 93304 -Fwd_GETX 6881 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93277 -Writeback_Ack 86393 -Writeback_Nack 43 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60651 +I Load 0 <-- I Ifetch 0 <-- -I Store 32658 +I Store 0 <-- I Inv 0 <-- -I Replacement 6836 +I Replacement 0 <-- -II Writeback_Nack 43 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6838 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86441 +M Replacement 0 <-- -MI Fwd_GETX 43 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86393 +MI Writeback_Ack 0 <-- -IS Data 60647 +IS Data 0 <-- -IM Data 32657 +IM Data 0 <-- --- L1Cache 3 --- - Event Counts - -Load 60350 +Load 0 Ifetch 0 -Store 32980 -Data 93323 -Fwd_GETX 6882 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93298 -Writeback_Ack 86405 -Writeback_Nack 53 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60350 +I Load 0 <-- I Ifetch 0 <-- -I Store 32980 +I Store 0 <-- I Inv 0 <-- -I Replacement 6827 +I Replacement 0 <-- -II Writeback_Nack 53 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6829 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86471 +M Replacement 0 <-- -MI Fwd_GETX 53 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86405 +MI Writeback_Ack 0 <-- -IS Data 60347 +IS Data 0 <-- -IM Data 32976 +IM Data 0 <-- --- L1Cache 4 --- - Event Counts - -Load 60918 +Load 0 Ifetch 0 -Store 32435 -Data 93342 -Fwd_GETX 6628 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93321 -Writeback_Ack 86677 -Writeback_Nack 45 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60918 +I Load 0 <-- I Ifetch 0 <-- -I Store 32435 +I Store 0 <-- I Inv 0 <-- -I Replacement 6583 +I Replacement 0 <-- -II Writeback_Nack 45 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6583 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86738 +M Replacement 0 <-- -MI Fwd_GETX 45 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86677 +MI Writeback_Ack 0 <-- -IS Data 60909 +IS Data 0 <-- -IM Data 32433 +IM Data 0 <-- --- L1Cache 5 --- - Event Counts - -Load 60399 +Load 0 Ifetch 0 -Store 32932 -Data 93317 -Fwd_GETX 6735 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93299 -Writeback_Ack 86554 -Writeback_Nack 55 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60399 +I Load 0 <-- I Ifetch 0 <-- -I Store 32932 +I Store 0 <-- I Inv 0 <-- -I Replacement 6679 +I Replacement 0 <-- -II Writeback_Nack 55 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6680 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86620 +M Replacement 0 <-- -MI Fwd_GETX 55 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86554 +MI Writeback_Ack 0 <-- -IS Data 60389 +IS Data 0 <-- -IM Data 32928 +IM Data 0 <-- --- L1Cache 6 --- - Event Counts - -Load 60601 +Load 0 Ifetch 0 -Store 32752 -Data 93344 -Fwd_GETX 6831 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93321 -Writeback_Ack 86483 -Writeback_Nack 61 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60601 +I Load 0 <-- I Ifetch 0 <-- -I Store 32752 +I Store 0 <-- I Inv 0 <-- -I Replacement 6769 +I Replacement 0 <-- -II Writeback_Nack 61 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6770 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86552 +M Replacement 0 <-- -MI Fwd_GETX 61 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86483 +MI Writeback_Ack 0 <-- -IS Data 60595 +IS Data 0 <-- -IM Data 32749 +IM Data 0 <-- --- L1Cache 7 --- - Event Counts - -Load 60612 +Load 0 Ifetch 0 -Store 32752 -Data 93354 -Fwd_GETX 6674 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93332 -Writeback_Ack 86650 -Writeback_Nack 56 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60612 +I Load 0 <-- I Ifetch 0 <-- -I Store 32752 +I Store 0 <-- I Inv 0 <-- -I Replacement 6618 +I Replacement 0 <-- -II Writeback_Nack 56 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6618 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86714 +M Replacement 0 <-- -MI Fwd_GETX 56 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86650 +MI Writeback_Ack 0 <-- -IS Data 60603 +IS Data 0 <-- -IM Data 32751 +IM Data 0 <-- diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr index af2769339..8fe2d4613 100755 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr @@ -1,76 +1,76 @@ -["-r", "tests/configs/../../src/mem/ruby/config/MI_example-homogeneous.rb", "-p", "8", "-m", "1", "-s", "1024"] +["-r", "tests/configs/../../src/mem/ruby/config/MI_example-homogeneous.rb", "-p", "8", "-m", "1", "-s", "1024", "-C", "256", "-A", "2", "-D", "1"] print config: 1 -system.cpu4: completed 10000 read accesses @3654068 -system.cpu1: completed 10000 read accesses @3658672 -system.cpu6: completed 10000 read accesses @3667702 -system.cpu0: completed 10000 read accesses @3693712 -system.cpu2: completed 10000 read accesses @3695692 -system.cpu7: completed 10000 read accesses @3702934 -system.cpu3: completed 10000 read accesses @3713843 -system.cpu5: completed 10000 read accesses @3747976 -system.cpu4: completed 20000 read accesses @6783252 -system.cpu6: completed 20000 read accesses @6788574 -system.cpu1: completed 20000 read accesses @6811444 -system.cpu2: completed 20000 read accesses @6811575 -system.cpu7: completed 20000 read accesses @6823208 -system.cpu3: completed 20000 read accesses @6833412 -system.cpu0: completed 20000 read accesses @6842332 -system.cpu5: completed 20000 read accesses @6892128 -system.cpu4: completed 30000 read accesses @9900552 -system.cpu6: completed 30000 read accesses @9919466 -system.cpu7: completed 30000 read accesses @9934195 -system.cpu3: completed 30000 read accesses @9940524 -system.cpu2: completed 30000 read accesses @9940526 -system.cpu0: completed 30000 read accesses @9949032 -system.cpu1: completed 30000 read accesses @10008962 -system.cpu5: completed 30000 read accesses @10013847 -system.cpu0: completed 40000 read accesses @12997824 -system.cpu3: completed 40000 read accesses @13026659 -system.cpu4: completed 40000 read accesses @13029141 -system.cpu6: completed 40000 read accesses @13053052 -system.cpu7: completed 40000 read accesses @13057445 -system.cpu2: completed 40000 read accesses @13075320 -system.cpu5: completed 40000 read accesses @13152513 -system.cpu1: completed 40000 read accesses @13163064 -system.cpu3: completed 50000 read accesses @16170822 -system.cpu0: completed 50000 read accesses @16183660 -system.cpu4: completed 50000 read accesses @16197183 -system.cpu6: completed 50000 read accesses @16212971 -system.cpu7: completed 50000 read accesses @16214970 -system.cpu5: completed 50000 read accesses @16230286 -system.cpu2: completed 50000 read accesses @16247930 -system.cpu1: completed 50000 read accesses @16329114 -system.cpu3: completed 60000 read accesses @19270542 -system.cpu0: completed 60000 read accesses @19311899 -system.cpu6: completed 60000 read accesses @19330724 -system.cpu4: completed 60000 read accesses @19371866 -system.cpu5: completed 60000 read accesses @19382898 -system.cpu7: completed 60000 read accesses @19384231 -system.cpu2: completed 60000 read accesses @19408394 -system.cpu1: completed 60000 read accesses @19459020 -system.cpu3: completed 70000 read accesses @22372299 -system.cpu6: completed 70000 read accesses @22442853 -system.cpu4: completed 70000 read accesses @22471794 -system.cpu0: completed 70000 read accesses @22486932 -system.cpu7: completed 70000 read accesses @22490492 -system.cpu5: completed 70000 read accesses @22527204 -system.cpu2: completed 70000 read accesses @22582036 -system.cpu1: completed 70000 read accesses @22588150 -system.cpu3: completed 80000 read accesses @25508231 -system.cpu6: completed 80000 read accesses @25562794 -system.cpu5: completed 80000 read accesses @25572200 -system.cpu0: completed 80000 read accesses @25620392 -system.cpu7: completed 80000 read accesses @25639710 -system.cpu4: completed 80000 read accesses @25649778 -system.cpu1: completed 80000 read accesses @25686718 -system.cpu2: completed 80000 read accesses @25733199 -system.cpu3: completed 90000 read accesses @28604804 -system.cpu6: completed 90000 read accesses @28707428 -system.cpu5: completed 90000 read accesses @28713115 -system.cpu0: completed 90000 read accesses @28743912 -system.cpu4: completed 90000 read accesses @28780814 -system.cpu7: completed 90000 read accesses @28781814 -system.cpu1: completed 90000 read accesses @28787396 -system.cpu2: completed 90000 read accesses @28868162 -system.cpu3: completed 100000 read accesses @31749698 +system.cpu7: completed 10000 read accesses @7023642 +system.cpu5: completed 10000 read accesses @7028438 +system.cpu3: completed 10000 read accesses @7034626 +system.cpu1: completed 10000 read accesses @7035790 +system.cpu2: completed 10000 read accesses @7062558 +system.cpu6: completed 10000 read accesses @7078882 +system.cpu0: completed 10000 read accesses @7080455 +system.cpu4: completed 10000 read accesses @7095500 +system.cpu1: completed 20000 read accesses @12915324 +system.cpu3: completed 20000 read accesses @12958052 +system.cpu5: completed 20000 read accesses @12993554 +system.cpu2: completed 20000 read accesses @13010879 +system.cpu4: completed 20000 read accesses @13014760 +system.cpu6: completed 20000 read accesses @13031684 +system.cpu7: completed 20000 read accesses @13051162 +system.cpu0: completed 20000 read accesses @13128234 +system.cpu3: completed 30000 read accesses @18784435 +system.cpu1: completed 30000 read accesses @18859194 +system.cpu5: completed 30000 read accesses @18903265 +system.cpu7: completed 30000 read accesses @18952860 +system.cpu4: completed 30000 read accesses @18981745 +system.cpu6: completed 30000 read accesses @18987772 +system.cpu0: completed 30000 read accesses @18993365 +system.cpu2: completed 30000 read accesses @18994061 +system.cpu3: completed 40000 read accesses @24748372 +system.cpu2: completed 40000 read accesses @24758090 +system.cpu1: completed 40000 read accesses @24768884 +system.cpu7: completed 40000 read accesses @24891866 +system.cpu0: completed 40000 read accesses @24907680 +system.cpu6: completed 40000 read accesses @24933908 +system.cpu5: completed 40000 read accesses @24949374 +system.cpu4: completed 40000 read accesses @24963853 +system.cpu3: completed 50000 read accesses @30655893 +system.cpu2: completed 50000 read accesses @30705287 +system.cpu1: completed 50000 read accesses @30752130 +system.cpu0: completed 50000 read accesses @30795942 +system.cpu5: completed 50000 read accesses @30809328 +system.cpu7: completed 50000 read accesses @30857254 +system.cpu6: completed 50000 read accesses @30935432 +system.cpu4: completed 50000 read accesses @30960853 +system.cpu3: completed 60000 read accesses @36647735 +system.cpu2: completed 60000 read accesses @36648110 +system.cpu1: completed 60000 read accesses @36690971 +system.cpu7: completed 60000 read accesses @36746000 +system.cpu5: completed 60000 read accesses @36746430 +system.cpu0: completed 60000 read accesses @36840602 +system.cpu6: completed 60000 read accesses @36900332 +system.cpu4: completed 60000 read accesses @36954562 +system.cpu2: completed 70000 read accesses @42614948 +system.cpu1: completed 70000 read accesses @42616200 +system.cpu5: completed 70000 read accesses @42679549 +system.cpu7: completed 70000 read accesses @42707038 +system.cpu3: completed 70000 read accesses @42725206 +system.cpu0: completed 70000 read accesses @42774272 +system.cpu6: completed 70000 read accesses @42850956 +system.cpu4: completed 70000 read accesses @42872700 +system.cpu5: completed 80000 read accesses @48577066 +system.cpu7: completed 80000 read accesses @48608169 +system.cpu2: completed 80000 read accesses @48616581 +system.cpu1: completed 80000 read accesses @48637808 +system.cpu0: completed 80000 read accesses @48726360 +system.cpu3: completed 80000 read accesses @48754087 +system.cpu4: completed 80000 read accesses @48848416 +system.cpu6: completed 80000 read accesses @48849321 +system.cpu5: completed 90000 read accesses @54536042 +system.cpu0: completed 90000 read accesses @54536954 +system.cpu7: completed 90000 read accesses @54554538 +system.cpu1: completed 90000 read accesses @54575168 +system.cpu2: completed 90000 read accesses @54648034 +system.cpu3: completed 90000 read accesses @54719200 +system.cpu6: completed 90000 read accesses @54807510 +system.cpu4: completed 90000 read accesses @54840954 +system.cpu1: completed 100000 read accesses @60455258 hack: be nice to actually delete the event here diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout index 465be4e7d..96bce5cec 100755 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout @@ -1,3 +1,5 @@ +Redirecting stdout to build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby/simout +Redirecting stderr to build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby/simerr M5 Simulator System Copyright (c) 2001-2008 @@ -5,11 +7,11 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 11 2009 13:41:17 -M5 revision be123e27612f+ 6494+ default tip -M5 started Aug 11 2009 13:45:58 -M5 executing on svvint01 +M5 compiled Nov 18 2009 16:36:52 +M5 revision c1d634e76817 6798 default qtip tip brad/ruby_memtest_refresh +M5 started Nov 18 2009 16:37:05 +M5 executing on cabr0354 command line: build/ALPHA_SE/m5.fast -d build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby -re tests/run.py build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... -Exiting @ tick 31749698 because maximum number of loads reached +Exiting @ tick 60455258 because maximum number of loads reached diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt index db2f23ad9..9b0c24527 100644 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt @@ -1,34 +1,34 @@ ---------- Begin Simulation Statistics ---------- -host_mem_usage 1507496 # Number of bytes of host memory used -host_seconds 3280.71 # Real time elapsed on the host -host_tick_rate 9678 # Simulator tick rate (ticks/s) +host_mem_usage 2438776 # Number of bytes of host memory used +host_seconds 3924.24 # Real time elapsed on the host +host_tick_rate 15406 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_seconds 0.000032 # Number of seconds simulated -sim_ticks 31749698 # Number of ticks simulated +sim_seconds 0.000060 # Number of seconds simulated +sim_ticks 60455258 # Number of ticks simulated system.cpu0.num_copies 0 # number of copy accesses completed -system.cpu0.num_reads 99565 # number of read accesses completed -system.cpu0.num_writes 53743 # number of write accesses completed +system.cpu0.num_reads 99982 # number of read accesses completed +system.cpu0.num_writes 53168 # number of write accesses completed system.cpu1.num_copies 0 # number of copy accesses completed -system.cpu1.num_reads 99657 # number of read accesses completed -system.cpu1.num_writes 53715 # number of write accesses completed +system.cpu1.num_reads 100000 # number of read accesses completed +system.cpu1.num_writes 53657 # number of write accesses completed system.cpu2.num_copies 0 # number of copy accesses completed -system.cpu2.num_reads 99204 # number of read accesses completed -system.cpu2.num_writes 53874 # number of write accesses completed +system.cpu2.num_reads 99758 # number of read accesses completed +system.cpu2.num_writes 53630 # number of write accesses completed system.cpu3.num_copies 0 # number of copy accesses completed -system.cpu3.num_reads 100000 # number of read accesses completed -system.cpu3.num_writes 53515 # number of write accesses completed +system.cpu3.num_reads 99707 # number of read accesses completed +system.cpu3.num_writes 53628 # number of write accesses completed system.cpu4.num_copies 0 # number of copy accesses completed -system.cpu4.num_reads 99473 # number of read accesses completed -system.cpu4.num_writes 53442 # number of write accesses completed +system.cpu4.num_reads 99425 # number of read accesses completed +system.cpu4.num_writes 53969 # number of write accesses completed system.cpu5.num_copies 0 # number of copy accesses completed -system.cpu5.num_reads 99627 # number of read accesses completed -system.cpu5.num_writes 53511 # number of write accesses completed +system.cpu5.num_reads 99810 # number of read accesses completed +system.cpu5.num_writes 53444 # number of write accesses completed system.cpu6.num_copies 0 # number of copy accesses completed -system.cpu6.num_reads 99662 # number of read accesses completed -system.cpu6.num_writes 53565 # number of write accesses completed +system.cpu6.num_reads 99532 # number of read accesses completed +system.cpu6.num_writes 53907 # number of write accesses completed system.cpu7.num_copies 0 # number of copy accesses completed -system.cpu7.num_reads 99533 # number of read accesses completed -system.cpu7.num_writes 53739 # number of write accesses completed +system.cpu7.num_reads 99819 # number of read accesses completed +system.cpu7.num_writes 53668 # number of write accesses completed ---------- End Simulation Statistics ---------- diff --git a/tests/test-progs/hello/bin/power/linux/hello b/tests/test-progs/hello/bin/power/linux/hello Binary files differnew file mode 100755 index 000000000..6619ae37f --- /dev/null +++ b/tests/test-progs/hello/bin/power/linux/hello diff --git a/util/regress b/util/regress index 856e9a1a6..347c565cb 100755 --- a/util/regress +++ b/util/regress @@ -41,7 +41,7 @@ optparser.add_option('-v', '--verbose', dest='verbose', action='store_true', help='echo commands before executing') optparser.add_option('--builds', dest='builds', default='ALPHA_SE,ALPHA_FS,MIPS_SE,' + \ - 'SPARC_SE,SPARC_FS,X86_SE,ARM_SE', + 'POWER_SE,SPARC_SE,SPARC_FS,X86_SE,ARM_SE', help='comma-separated list of build targets to test ' " (default: '%default')" ) optparser.add_option('--variants', dest='variants', diff --git a/util/rundiff b/util/rundiff index cd2527e54..7e0a77057 100755 --- a/util/rundiff +++ b/util/rundiff @@ -166,7 +166,11 @@ sub printdiff # Set $postcontext to print the next $postcontext_lines matching lines. $postcontext = $postcontext_lines; - STDOUT->flush(); + # Normally we flush after the postcontext lines are printed, but if + # the user has decreed that there aren't any we need to flush now + if ($postcontext == 0) { + STDOUT->flush(); + } } @@ -291,10 +295,12 @@ while (1) { # figure out what to do with this line if ($postcontext > 0) { # we're in the post-context of a diff: print it - $postcontext--; print ' ', $l1; $lineno1++; $lineno2++; + if (--$postcontext == 0) { + STDOUT->flush(); + } } else { # we're in the middle of a matching region... save this diff --git a/util/slicc b/util/slicc new file mode 100755 index 000000000..07bd73ffa --- /dev/null +++ b/util/slicc @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +if __name__ == "__main__": + import sys + from os.path import dirname, join + + base = dirname(__file__) + sys.path.insert(1, join(base, "../src/mem")) + sys.path.insert(1, join(base, "../src/python")) + sys.path.insert(1, join(base, "../ext/ply")) + + import slicc.main + slicc.main.main() |