Merge iceaxe.:/Volumes/work/research/m5/head
authorNathan Binkert <binkertn@umich.edu>
Mon, 12 Jun 2006 02:01:34 +0000 (22:01 -0400)
committerNathan Binkert <binkertn@umich.edu>
Mon, 12 Jun 2006 02:01:34 +0000 (22:01 -0400)
into  iceaxe.:/Volumes/work/research/m5/merge

src/cpu/simple/base.cc:
src/kern/kernel_stats.cc:
src/kern/kernel_stats.hh:
src/kern/system_events.cc:
src/kern/system_events.hh:
src/python/m5/objects/System.py:
src/sim/system.cc:
src/sim/system.hh:
    hand merge

--HG--
rename : build/SConstruct => SConstruct
rename : SConscript => src/SConscript
rename : arch/alpha/freebsd/system.cc => src/arch/alpha/freebsd/system.cc
rename : arch/alpha/linux/system.cc => src/arch/alpha/linux/system.cc
rename : arch/alpha/linux/system.hh => src/arch/alpha/linux/system.hh
rename : arch/alpha/system.cc => src/arch/alpha/system.cc
rename : arch/alpha/tru64/system.cc => src/arch/alpha/tru64/system.cc
rename : base/statistics.cc => src/base/statistics.cc
rename : base/statistics.hh => src/base/statistics.hh
rename : base/stats/mysql.cc => src/base/stats/mysql.cc
rename : base/stats/mysql.hh => src/base/stats/mysql.hh
rename : base/stats/statdb.cc => src/base/stats/statdb.cc
rename : base/stats/statdb.hh => src/base/stats/statdb.hh
rename : base/stats/text.cc => src/base/stats/text.cc
rename : base/stats/text.hh => src/base/stats/text.hh
rename : cpu/simple/cpu.cc => src/cpu/simple/base.cc
rename : kern/kernel_stats.cc => src/kern/kernel_stats.cc
rename : kern/kernel_stats.hh => src/kern/kernel_stats.hh
rename : kern/system_events.cc => src/kern/system_events.cc
rename : kern/system_events.hh => src/kern/system_events.hh
rename : python/m5/objects/System.py => src/python/m5/objects/System.py
rename : sim/system.cc => src/sim/system.cc
rename : sim/system.hh => src/sim/system.hh
rename : test/stattest.cc => src/unittest/stattest.cc
extra : convert_revision : 4bb576a2bf5e32784efc48030bd776c6c7c29a7c

28 files changed:
1  2 
SConstruct
src/SConscript
src/arch/alpha/freebsd/system.cc
src/arch/alpha/linux/system.cc
src/arch/alpha/linux/system.hh
src/arch/alpha/system.cc
src/arch/alpha/tru64/system.cc
src/base/statistics.cc
src/base/statistics.hh
src/base/stats/mysql.cc
src/base/stats/mysql.hh
src/base/stats/statdb.cc
src/base/stats/statdb.hh
src/base/stats/text.cc
src/base/stats/text.hh
src/cpu/simple/base.cc
src/kern/kernel_stats.cc
src/kern/kernel_stats.hh
src/kern/system_events.cc
src/kern/system_events.hh
src/python/m5/objects/System.py
src/sim/system.cc
src/sim/system.hh
src/unittest/stattest.cc
util/stats/db.py
util/stats/dbinit.py
util/stats/info.py
util/stats/stats.py

diff --cc SConstruct
index fb6bc609e2bf89396fe1ef8325e632636abd86b9,0000000000000000000000000000000000000000..0cf15b1f971aba4474460304f652c74ad56521ae
mode 100644,000000..100644
--- /dev/null
@@@ -1,507 -1,0 +1,505 @@@
-     BoolOption('STATS_BINNING', 'Bin statistics by CPU mode', have_mysql),
 +# -*- mode:python -*-
 +
 +# 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
 +# 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
 +
 +###################################################
 +#
 +# SCons top-level build description (SConstruct) file.
 +#
 +# While in this directory ('m5'), just type 'scons' to build the default
 +# configuration (see below), or type 'scons build/<CONFIG>/<binary>'
 +# to build some other configuration (e.g., 'build/ALPHA_FS/m5.opt' for
 +# the optimized full-system version).
 +#
 +# You can build M5 in a different directory as long as there is a
 +# 'build/<CONFIG>' somewhere along the target path.  The build system
 +# expdects that all configs under the same build directory are being
 +# built for the same host system.
 +#
 +# Examples:
 +#   These two commands are equivalent.  The '-u' option tells scons to
 +#   search up the directory tree for this SConstruct file.
 +#   % cd <path-to-src>/m5 ; scons build/ALPHA_FS/m5.debug
 +#   % cd <path-to-src>/m5/build/ALPHA_FS; scons -u m5.debug
 +#   These two commands are equivalent and demonstrate building in a
 +#   directory outside of the source tree.  The '-C' option tells scons
 +#   to chdir to the specified directory to find this SConstruct file.
 +#   % cd <path-to-src>/m5 ; scons /local/foo/build/ALPHA_FS/m5.debug
 +#   % cd /local/foo/build/ALPHA_FS; scons -C <path-to-src>/m5 m5.debug
 +#
 +# You can use 'scons -H' to print scons options.  If you're in this
 +# 'm5' directory (or use -u or -C to tell scons where to find this
 +# file), you can use 'scons -h' to print all the M5-specific build
 +# options as well.
 +#
 +###################################################
 +
 +# Python library imports
 +import sys
 +import os
 +
 +# Check for recent-enough Python and SCons versions.  If your system's
 +# default installation of Python is not recent enough, you can use a
 +# non-default installation of the Python interpreter by either (1)
 +# rearranging your PATH so that scons finds the non-default 'python'
 +# first or (2) explicitly invoking an alternative interpreter on the
 +# scons script, e.g., "/usr/local/bin/python2.4 `which scons` [args]".
 +EnsurePythonVersion(2,4)
 +
 +# Ironically, SCons 0.96 dies if you give EnsureSconsVersion a
 +# 3-element version number.
 +min_scons_version = (0,96,91)
 +try:
 +    EnsureSConsVersion(*min_scons_version)
 +except:
 +    print "Error checking current SCons version."
 +    print "SCons", ".".join(map(str,min_scons_version)), "or greater required."
 +    Exit(2)
 +    
 +
 +# The absolute path to the current directory (where this file lives).
 +ROOT = Dir('.').abspath
 +
 +# Paths to the M5 and external source trees.
 +SRCDIR = os.path.join(ROOT, 'src')
 +
 +# tell python where to find m5 python code
 +sys.path.append(os.path.join(ROOT, 'src/python'))
 +
 +###################################################
 +#
 +# Figure out which configurations to set up based on the path(s) of
 +# the target(s).
 +#
 +###################################################
 +
 +# Find default configuration & binary.
 +Default(os.environ.get('M5_DEFAULT_BINARY', 'build/ALPHA_SE/m5.debug'))
 +
 +# Ask SCons which directory it was invoked from.
 +launch_dir = GetLaunchDir()
 +
 +# Make targets relative to invocation directory
 +abs_targets = map(lambda x: os.path.normpath(os.path.join(launch_dir, str(x))),
 +                  BUILD_TARGETS)
 +
 +# helper function: find last occurrence of element in list
 +def rfind(l, elt, offs = -1):
 +    for i in range(len(l)+offs, 0, -1):
 +        if l[i] == elt:
 +            return i
 +    raise ValueError, "element not found"
 +
 +# Each target must have 'build' in the interior of the path; the
 +# directory below this will determine the build parameters.  For
 +# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we
 +# recognize that ALPHA_SE specifies the configuration because it
 +# follow 'build' in the bulid path.
 +
 +# Generate a list of the unique build roots and configs that the
 +# collected targets reference.
 +build_paths = []
 +build_root = None
 +for t in abs_targets:
 +    path_dirs = t.split('/')
 +    try:
 +        build_top = rfind(path_dirs, 'build', -2)
 +    except:
 +        print "Error: no non-leaf 'build' dir found on target path", t
 +        Exit(1)
 +    this_build_root = os.path.join('/',*path_dirs[:build_top+1])
 +    if not build_root:
 +        build_root = this_build_root
 +    else:
 +        if this_build_root != build_root:
 +            print "Error: build targets not under same build root\n"\
 +                  "  %s\n  %s" % (build_root, this_build_root)
 +            Exit(1)
 +    build_path = os.path.join('/',*path_dirs[:build_top+2])
 +    if build_path not in build_paths:
 +        build_paths.append(build_path)
 +
 +###################################################
 +#
 +# Set up the default build environment.  This environment is copied
 +# and modified according to each selected configuration.
 +#
 +###################################################
 +
 +env = Environment(ENV = os.environ,  # inherit user's environment vars
 +                  ROOT = ROOT,
 +                  SRCDIR = SRCDIR)
 +
 +env.SConsignFile("sconsign")
 +
 +# Default duplicate option is to use hard links, but this messes up
 +# when you use emacs to edit a file in the target dir, as emacs moves
 +# file to file~ then copies to file, breaking the link.  Symbolic
 +# (soft) links work better.
 +env.SetOption('duplicate', 'soft-copy')
 +
 +# I waffle on this setting... it does avoid a few painful but
 +# unnecessary builds, but it also seems to make trivial builds take
 +# noticeably longer.
 +if False:
 +    env.TargetSignatures('content')
 +
 +# M5_PLY is used by isa_parser.py to find the PLY package.
 +env.Append(ENV = { 'M5_PLY' : Dir('ext/ply') })
 +
 +# Set up default C++ compiler flags
 +env.Append(CCFLAGS='-pipe')
 +env.Append(CCFLAGS='-fno-strict-aliasing')
 +env.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
 +if sys.platform == 'cygwin':
 +    # cygwin has some header file issues...
 +    env.Append(CCFLAGS=Split("-Wno-uninitialized"))
 +env.Append(CPPPATH=[Dir('ext/dnet')])
 +
 +# Find Python include and library directories for embedding the
 +# interpreter.  For consistency, we will use the same Python
 +# installation used to run scons (and thus this script).  If you want
 +# to link in an alternate version, see above for instructions on how
 +# to invoke scons with a different copy of the Python interpreter.
 +
 +# Get brief Python version name (e.g., "python2.4") for locating
 +# include & library files
 +py_version_name = 'python' + sys.version[:3]
 +
 +# include path, e.g. /usr/local/include/python2.4
 +env.Append(CPPPATH = os.path.join(sys.exec_prefix, 'include', py_version_name))
 +env.Append(LIBS = py_version_name)
 +# add library path too if it's not in the default place
 +if sys.exec_prefix != '/usr':
 +    env.Append(LIBPATH = os.path.join(sys.exec_prefix, 'lib'))
 +
 +# Set up SWIG flags & scanner
 +
 +env.Append(SWIGFLAGS=Split('-c++ -python -modern $_CPPINCFLAGS'))
 +
 +import SCons.Scanner
 +
 +swig_inc_re = '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
 +
 +swig_scanner = SCons.Scanner.ClassicCPP("SwigScan", ".i", "CPPPATH",
 +                                        swig_inc_re)
 +
 +env.Append(SCANNERS = swig_scanner)
 +
 +# Other default libraries
 +env.Append(LIBS=['z'])
 +
 +# Platform-specific configuration.  Note again that we assume that all
 +# builds under a given build root run on the same host platform.
 +conf = Configure(env,
 +                 conf_dir = os.path.join(build_root, '.scons_config'),
 +                 log_file = os.path.join(build_root, 'scons_config.log'))
 +
 +# Check for <fenv.h> (C99 FP environment control)
 +have_fenv = conf.CheckHeader('fenv.h', '<>')
 +if not have_fenv:
 +    print "Warning: Header file <fenv.h> not found."
 +    print "         This host has no IEEE FP rounding mode control."
 +
 +# Check for mysql.
 +mysql_config = WhereIs('mysql_config')
 +have_mysql = mysql_config != None
 +
 +# Check MySQL version.
 +if have_mysql:
 +    mysql_version = os.popen(mysql_config + ' --version').read()
 +    mysql_version = mysql_version.split('.')
 +    mysql_major = int(mysql_version[0])
 +    mysql_minor = int(mysql_version[1])
 +    # This version check is probably overly conservative, but it deals
 +    # with the versions we have installed.
 +    if mysql_major < 4 or (mysql_major == 4 and mysql_minor < 1):
 +        print "Warning: MySQL v4.1 or newer required."
 +        have_mysql = False
 +
 +# Set up mysql_config commands.
 +if have_mysql:
 +    mysql_config_include = mysql_config + ' --include'
 +    if os.system(mysql_config_include + ' > /dev/null') != 0:
 +        # older mysql_config versions don't support --include, use
 +        # --cflags instead
 +        mysql_config_include = mysql_config + ' --cflags | sed s/\\\'//g'
 +    # This seems to work in all versions
 +    mysql_config_libs = mysql_config + ' --libs'
 +
 +env = conf.Finish()
 +
 +# Define the universe of supported ISAs
 +env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips']
 +
 +# Define the universe of supported CPU models
 +env['ALL_CPU_LIST'] = ['AtomicSimpleCPU', 'TimingSimpleCPU',
 +                       'FullCPU', 'AlphaFullCPU',
 +                       'OzoneSimpleCPU', 'OzoneCPU', 'CheckerCPU']
 +
 +# Sticky options get saved in the options file so they persist from
 +# one invocation to the next (unless overridden, in which case the new
 +# value becomes sticky).
 +sticky_opts = Options(args=ARGUMENTS)
 +sticky_opts.AddOptions(
 +    EnumOption('TARGET_ISA', 'Target ISA', 'alpha', env['ALL_ISA_LIST']),
 +    BoolOption('FULL_SYSTEM', 'Full-system support', False),
 +    # There's a bug in scons 0.96.1 that causes ListOptions with list
 +    # values (more than one value) not to be able to be restored from
 +    # a saved option file.  If this causes trouble then upgrade to
 +    # scons 0.96.90 or later.
 +    ListOption('CPU_MODELS', 'CPU models', 'AtomicSimpleCPU,TimingSimpleCPU',
 +               env['ALL_CPU_LIST']),
 +    BoolOption('ALPHA_TLASER',
 +               'Model Alpha TurboLaser platform (vs. Tsunami)', False),
 +    BoolOption('NO_FAST_ALLOC', 'Disable fast object allocator', False),
 +    BoolOption('EFENCE', 'Link with Electric Fence malloc debugger',
 +               False),
 +    BoolOption('SS_COMPATIBLE_FP',
 +               'Make floating-point results compatible with SimpleScalar',
 +               False),
 +    BoolOption('USE_SSE2',
 +               'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts',
 +               False),
-                      'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP', \
-                      'STATS_BINNING']
 +    BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
 +    BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
 +    ('CC', 'C compiler', os.environ.get('CC', env['CC'])),
 +    ('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])),
 +    BoolOption('BATCH', 'Use batch pool for build and tests', False),
 +    ('BATCH_CMD', 'Batch pool submission command name', 'qdo')
 +    )
 +
 +# Non-sticky options only apply to the current build.
 +nonsticky_opts = Options(args=ARGUMENTS)
 +nonsticky_opts.AddOptions(
 +    BoolOption('update_ref', 'Update test reference outputs', False)
 +    )
 +
 +# These options get exported to #defines in config/*.hh (see m5/SConscript).
 +env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
++                     'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP']
 +
 +# Define a handy 'no-op' action
 +def no_action(target, source, env):
 +    return 0
 +
 +env.NoAction = Action(no_action, None)
 +
 +###################################################
 +#
 +# Define a SCons builder for configuration flag headers.
 +#
 +###################################################
 +
 +# This function generates a config header file that #defines the
 +# option symbol to the current option setting (0 or 1).  The source
 +# operands are the name of the option and a Value node containing the
 +# value of the option.
 +def build_config_file(target, source, env):
 +    (option, value) = [s.get_contents() for s in source]
 +    f = file(str(target[0]), 'w')
 +    print >> f, '#define', option, value
 +    f.close()
 +    return None
 +
 +# Generate the message to be printed when building the config file.
 +def build_config_file_string(target, source, env):
 +    (option, value) = [s.get_contents() for s in source]
 +    return "Defining %s as %s in %s." % (option, value, target[0])
 +
 +# Combine the two functions into a scons Action object.
 +config_action = Action(build_config_file, build_config_file_string)
 +
 +# The emitter munges the source & target node lists to reflect what
 +# we're really doing.
 +def config_emitter(target, source, env):
 +    # extract option name from Builder arg
 +    option = str(target[0])
 +    # True target is config header file
 +    target = os.path.join('config', option.lower() + '.hh')
 +    # Force value to 0/1 even if it's a Python bool
 +    val = int(eval(str(env[option])))
 +    # Sources are option name & value (packaged in SCons Value nodes)
 +    return ([target], [Value(option), Value(val)])
 +
 +config_builder = Builder(emitter = config_emitter, action = config_action)
 +
 +env.Append(BUILDERS = { 'ConfigFile' : config_builder })
 +
 +###################################################
 +#
 +# Define a SCons builder for copying files.  This is used by the
 +# Python zipfile code in src/python/SConscript, but is placed up here
 +# since it's potentially more generally applicable.
 +#
 +###################################################
 +
 +copy_builder = Builder(action = Copy("$TARGET", "$SOURCE"))
 +
 +env.Append(BUILDERS = { 'CopyFile' : copy_builder })
 +
 +###################################################
 +#
 +# Define a simple SCons builder to concatenate files.
 +#
 +# Used to append the Python zip archive to the executable.
 +#
 +###################################################
 +
 +concat_builder = Builder(action = Action(['cat $SOURCES > $TARGET',
 +                                          'chmod +x $TARGET']))
 +
 +env.Append(BUILDERS = { 'Concat' : concat_builder })
 +
 +
 +# base help text
 +help_text = '''
 +Usage: scons [scons options] [build options] [target(s)]
 +
 +'''
 +
 +# libelf build is shared across all configs in the build root.
 +env.SConscript('ext/libelf/SConscript',
 +               build_dir = os.path.join(build_root, 'libelf'),
 +               exports = 'env')
 +
 +###################################################
 +#
 +# Define build environments for selected configurations.
 +#
 +###################################################
 +
 +# rename base env
 +base_env = env
 +
 +for build_path in build_paths:
 +    print "Building in", build_path
 +    # build_dir is the tail component of build path, and is used to
 +    # determine the build parameters (e.g., 'ALPHA_SE')
 +    (build_root, build_dir) = os.path.split(build_path)
 +    # Make a copy of the build-root environment to use for this config.
 +    env = base_env.Copy()
 +
 +    # Set env options according to the build directory config.
 +    sticky_opts.files = []
 +    # Options for $BUILD_ROOT/$BUILD_DIR are stored in
 +    # $BUILD_ROOT/options/$BUILD_DIR so you can nuke
 +    # $BUILD_ROOT/$BUILD_DIR without losing your options settings.
 +    current_opts_file = os.path.join(build_root, 'options', build_dir)
 +    if os.path.isfile(current_opts_file):
 +        sticky_opts.files.append(current_opts_file)
 +        print "Using saved options file %s" % current_opts_file
 +    else:
 +        # Build dir-specific options file doesn't exist.
 +
 +        # Make sure the directory is there so we can create it later
 +        opt_dir = os.path.dirname(current_opts_file)
 +        if not os.path.isdir(opt_dir):
 +            os.mkdir(opt_dir)
 +
 +        # Get default build options from source tree.  Options are
 +        # normally determined by name of $BUILD_DIR, but can be
 +        # overriden by 'default=' arg on command line.
 +        default_opts_file = os.path.join('build_opts',
 +                                         ARGUMENTS.get('default', build_dir))
 +        if os.path.isfile(default_opts_file):
 +            sticky_opts.files.append(default_opts_file)
 +            print "Options file %s not found,\n  using defaults in %s" \
 +                  % (current_opts_file, default_opts_file)
 +        else:
 +            print "Error: cannot find options file %s or %s" \
 +                  % (current_opts_file, default_opts_file)
 +            Exit(1)
 +
 +    # Apply current option settings to env
 +    sticky_opts.Update(env)
 +    nonsticky_opts.Update(env)
 +
 +    help_text += "Sticky options for %s:\n" % build_dir \
 +                 + sticky_opts.GenerateHelpText(env) \
 +                 + "\nNon-sticky options for %s:\n" % build_dir \
 +                 + nonsticky_opts.GenerateHelpText(env)
 +
 +    # Process option settings.
 +
 +    if not have_fenv and env['USE_FENV']:
 +        print "Warning: <fenv.h> not available; " \
 +              "forcing USE_FENV to False in", build_dir + "."
 +        env['USE_FENV'] = False
 +
 +    if not env['USE_FENV']:
 +        print "Warning: No IEEE FP rounding mode control in", build_dir + "."
 +        print "         FP results may deviate slightly from other platforms."
 +
 +    if env['EFENCE']:
 +        env.Append(LIBS=['efence'])
 +
 +    if env['USE_MYSQL']:
 +        if not have_mysql:
 +            print "Warning: MySQL not available; " \
 +                  "forcing USE_MYSQL to False in", build_dir + "."
 +            env['USE_MYSQL'] = False
 +        else:
 +            print "Compiling in", build_dir, "with MySQL support."
 +            env.ParseConfig(mysql_config_libs)
 +            env.ParseConfig(mysql_config_include)
 +
 +    # Save sticky option settings back to current options file
 +    sticky_opts.Save(current_opts_file, env)
 +
 +    # Do this after we save setting back, or else we'll tack on an
 +    # extra 'qdo' every time we run scons.
 +    if env['BATCH']:
 +        env['CC']  = env['BATCH_CMD'] + ' ' + env['CC']
 +        env['CXX'] = env['BATCH_CMD'] + ' ' + env['CXX']
 +
 +    if env['USE_SSE2']:
 +        env.Append(CCFLAGS='-msse2')
 +
 +    # The m5/SConscript file sets up the build rules in 'env' according
 +    # to the configured options.  It returns a list of environments,
 +    # one for each variant build (debug, opt, etc.)
 +    envList = SConscript('src/SConscript', build_dir = build_path,
 +                         exports = 'env')
 +
 +    # Set up the regression tests for each build.
 +#    for e in envList:
 +#        SConscript('m5-test/SConscript',
 +#                   build_dir = os.path.join(build_dir, 'test', e.Label),
 +#                   exports = { 'env' : e }, duplicate = False)
 +
 +Help(help_text)
 +
 +###################################################
 +#
 +# Let SCons do its thing.  At this point SCons will use the defined
 +# build environments to build the requested targets.
 +#
 +###################################################
 +
diff --cc src/SConscript
index b166720a1cd4bba3a316535641328a12c09f0e0b,0000000000000000000000000000000000000000..a1c18711c7d0ecee217619a6ff259efa9aa50ff6
mode 100644,000000..100644
--- /dev/null
@@@ -1,399 -1,0 +1,398 @@@
-       kern/kernel_binning.cc
 +# -*- mode:python -*-
 +
 +# 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
 +# 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
 +
 +import os
 +import sys
 +from os.path import isdir
 +
 +# This file defines how to build a particular configuration of M5
 +# based on variable settings in the 'env' build environment.
 +
 +# Import build environment variable from SConstruct.
 +Import('env')
 +
 +###################################################
 +#
 +# Define needed sources.
 +#
 +###################################################
 +
 +# Base sources used by all configurations.
 +
 +base_sources = Split('''
 +      base/circlebuf.cc
 +      base/cprintf.cc
 +      base/fast_alloc.cc
 +      base/fifo_buffer.cc
 +      base/hostinfo.cc
 +      base/hybrid_pred.cc
 +      base/inifile.cc
 +      base/intmath.cc
 +      base/match.cc
 +      base/misc.cc
 +      base/output.cc
 +      base/pollevent.cc
 +      base/range.cc
 +      base/random.cc
 +      base/sat_counter.cc
 +        base/serializer.cc
 +      base/socket.cc
 +      base/statistics.cc
 +      base/str.cc
 +      base/time.cc
 +      base/trace.cc
 +      base/traceflags.cc
 +      base/userinfo.cc
 +      base/compression/lzss_compression.cc
 +      base/loader/aout_object.cc
 +      base/loader/ecoff_object.cc
 +      base/loader/elf_object.cc
 +      base/loader/object_file.cc
 +      base/loader/symtab.cc
 +      base/stats/events.cc
 +      base/stats/statdb.cc
 +      base/stats/visit.cc
 +      base/stats/text.cc
 +
 +        cpu/activity.cc
 +      cpu/base.cc
 +      cpu/cpuevent.cc
 +      cpu/exetrace.cc
 +        cpu/op_class.cc
 +      cpu/pc_event.cc
 +        cpu/quiesce_event.cc
 +      cpu/static_inst.cc
 +        cpu/sampler/sampler.cc
 +        cpu/simple_thread.cc
 +        cpu/thread_state.cc
 +
 +        encumbered/cpu/full/fu_pool.cc
 +        
 +        mem/bridge.cc
 +        mem/bus.cc
 +        mem/connector.cc
 +        mem/mem_object.cc
 +        mem/packet.cc
 +        mem/physical.cc
 +        mem/port.cc
 +
 +      sim/builder.cc
 +      sim/configfile.cc
 +      sim/debug.cc
 +      sim/eventq.cc
 +      sim/faults.cc
 +      sim/main.cc
 +        python/swig/main_wrap.cc
 +      sim/param.cc
 +      sim/profile.cc
 +      sim/root.cc
 +      sim/serialize.cc
 +      sim/sim_events.cc
 +      sim/sim_object.cc
 +      sim/startup.cc
 +      sim/stat_context.cc
 +      sim/stat_control.cc
 +      sim/system.cc
 +      sim/trace_context.cc
 +        ''')
 +
 +# Old FullCPU sources
 +full_cpu_sources = Split('''
 +      encumbered/cpu/full/bpred.cc
 +      encumbered/cpu/full/commit.cc
 +      encumbered/cpu/full/cpu.cc
 +      encumbered/cpu/full/create_vector.cc
 +      encumbered/cpu/full/cv_spec_state.cc
 +      encumbered/cpu/full/dd_queue.cc
 +      encumbered/cpu/full/dep_link.cc
 +      encumbered/cpu/full/dispatch.cc
 +      encumbered/cpu/full/dyn_inst.cc
 +      encumbered/cpu/full/execute.cc
 +      encumbered/cpu/full/fetch.cc
 +      encumbered/cpu/full/floss_reasons.cc
 +      encumbered/cpu/full/fu_pool.cc
 +      encumbered/cpu/full/inst_fifo.cc
 +      encumbered/cpu/full/instpipe.cc
 +      encumbered/cpu/full/issue.cc
 +      encumbered/cpu/full/ls_queue.cc
 +      encumbered/cpu/full/machine_queue.cc
 +        encumbered/cpu/full/pipetrace.cc
 +        encumbered/cpu/full/readyq.cc
 +        encumbered/cpu/full/reg_info.cc
 +        encumbered/cpu/full/rob_station.cc
 +        encumbered/cpu/full/spec_memory.cc
 +        encumbered/cpu/full/spec_state.cc
 +        encumbered/cpu/full/storebuffer.cc
 +        encumbered/cpu/full/writeback.cc
 +        encumbered/cpu/full/iq/iq_station.cc
 +        encumbered/cpu/full/iq/iqueue.cc
 +        encumbered/cpu/full/iq/segmented/chain_info.cc
 +        encumbered/cpu/full/iq/segmented/chain_wire.cc
 +        encumbered/cpu/full/iq/segmented/iq_seg.cc
 +        encumbered/cpu/full/iq/segmented/iq_segmented.cc
 +        encumbered/cpu/full/iq/segmented/seg_chain.cc
 +        encumbered/cpu/full/iq/seznec/iq_seznec.cc
 +        encumbered/cpu/full/iq/standard/iq_standard.cc
 +        ''')
 +
 +trace_reader_sources = Split('''
 +        cpu/trace/reader/mem_trace_reader.cc
 +        cpu/trace/reader/ibm_reader.cc
 +        cpu/trace/reader/itx_reader.cc
 +        cpu/trace/reader/m5_reader.cc
 +        cpu/trace/opt_cpu.cc
 +        cpu/trace/trace_cpu.cc
 +        ''')
 +
 +
 +
 +# MySql sources
 +mysql_sources = Split('''
 +      base/mysql.cc
 +      base/stats/mysql.cc
 +        ''')
 +
 +# Full-system sources
 +full_system_sources = Split('''
 +      base/crc.cc
 +      base/inet.cc
 +      base/remote_gdb.cc
 +
 +      cpu/intr_control.cc
 +        cpu/profile.cc
 +
 +      dev/alpha_console.cc
 +      dev/baddev.cc
 +      dev/disk_image.cc
 +      dev/etherbus.cc
 +      dev/etherdump.cc
 +      dev/etherint.cc
 +      dev/etherlink.cc
 +      dev/etherpkt.cc
 +      dev/ethertap.cc 
 +        dev/ide_ctrl.cc
 +      dev/ide_disk.cc
 +      dev/io_device.cc
 +      dev/isa_fake.cc
 +      dev/ns_gige.cc
 +      dev/pciconfigall.cc
 +      dev/pcidev.cc
 +      dev/pcifake.cc
 +      dev/pktfifo.cc
 +      dev/platform.cc
 +        dev/simconsole.cc
 +      dev/simple_disk.cc
 +      dev/sinic.cc
 +      dev/tsunami.cc
 +      dev/tsunami_cchip.cc
 +      dev/tsunami_io.cc
 +      dev/tsunami_fake.cc
 +      dev/tsunami_pchip.cc
 +
 +      dev/uart.cc
 +      dev/uart8250.cc
 +
 +      kern/kernel_stats.cc
 +      kern/system_events.cc
 +      kern/linux/events.cc
 +      kern/linux/linux_syscalls.cc
 +      kern/linux/printk.cc
 +
 +        mem/vport.cc
 +
 +      sim/pseudo_inst.cc
 +        ''')
 +
 +
 +if env['TARGET_ISA'] == 'alpha':
 +    full_system_sources += Split('''
 +      kern/tru64/dump_mbuf.cc
 +      kern/tru64/printf.cc
 +      kern/tru64/tru64_events.cc
 +      kern/tru64/tru64_syscalls.cc
 +        ''')
 +
 +# turbolaser encumbered sources
 +turbolaser_sources = Split('''
 +      encumbered/dev/dma.cc
 +      encumbered/dev/etherdev.cc
 +      encumbered/dev/scsi.cc
 +      encumbered/dev/scsi_ctrl.cc
 +      encumbered/dev/scsi_disk.cc
 +      encumbered/dev/scsi_none.cc
 +      encumbered/dev/tlaser_clock.cc
 +      encumbered/dev/tlaser_ipi.cc
 +      encumbered/dev/tlaser_mbox.cc
 +      encumbered/dev/tlaser_mc146818.cc
 +      encumbered/dev/tlaser_node.cc
 +      encumbered/dev/tlaser_pcia.cc
 +      encumbered/dev/tlaser_pcidev.cc
 +      encumbered/dev/tlaser_serial.cc
 +      encumbered/dev/turbolaser.cc
 +      encumbered/dev/uart8530.cc
 +        ''')
 +
 +# Syscall emulation (non-full-system) sources
 +syscall_emulation_sources = Split('''
 +        mem/translating_port.cc
 +        mem/page_table.cc
 +      sim/process.cc
 +      sim/syscall_emul.cc
 +        ''')
 +
 +#if env['TARGET_ISA'] == 'alpha':
 +#    syscall_emulation_sources += Split('''
 +#        kern/tru64/tru64.cc
 +#        ''')
 +
 +alpha_eio_sources = Split('''
 +      encumbered/eio/exolex.cc
 +      encumbered/eio/libexo.cc
 +      encumbered/eio/eio.cc
 +        ''')
 +
 +if env['TARGET_ISA'] == 'ALPHA_ISA':
 +    syscall_emulation_sources += alpha_eio_sources
 +    
 +memtest_sources = Split('''
 +      cpu/memtest/memtest.cc
 +        ''')
 +
 +# Include file paths are rooted in this directory.  SCons will
 +# automatically expand '.' to refer to both the source directory and
 +# the corresponding build directory to pick up generated include
 +# files.
 +env.Append(CPPPATH=Dir('.'))
 +
 +# Add a flag defining what THE_ISA should be for all compilation
 +env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
 +
 +arch_sources = SConscript('arch/SConscript', exports = 'env')
 +
 +cpu_sources = SConscript('cpu/SConscript', exports = 'env')
 +
 +# This is outside of cpu/SConscript since the source directory isn't
 +# underneath 'cpu'.
 +if 'FullCPU' in env['CPU_MODELS']:
 +    cpu_sources += full_cpu_sources
 +
 +# Set up complete list of sources based on configuration.
 +sources = base_sources + arch_sources + cpu_sources
 +
 +if env['FULL_SYSTEM']:
 +    sources += full_system_sources
 +    if env['ALPHA_TLASER']:
 +        sources += turbolaser_sources
 +else:
 +    sources += syscall_emulation_sources
 +
 +if env['USE_MYSQL']:
 +    sources += mysql_sources
 +
 +for opt in env.ExportOptions:
 +    env.ConfigFile(opt)
 +
 +###################################################
 +#
 +# Special build rules.
 +#
 +###################################################
 +
 +# base/traceflags.{cc,hh} are generated from base/traceflags.py.
 +# $TARGET.base will expand to "<build-dir>/base/traceflags".
 +env.Command(Split('base/traceflags.hh base/traceflags.cc'),
 +            'base/traceflags.py',
 +            'python $SOURCE $TARGET.base')
 +
 +SConscript('python/SConscript', exports = ['env'])
 +
 +# This function adds the specified sources to the given build
 +# environment, and returns a list of all the corresponding SCons
 +# Object nodes (including an extra one for date.cc).  We explicitly
 +# add the Object nodes so we can set up special dependencies for
 +# date.cc.
 +def make_objs(sources, env):
 +    objs = [env.Object(s) for s in sources]
 +    # make date.cc depend on all other objects so it always gets
 +    # recompiled whenever anything else does
 +    date_obj = env.Object('base/date.cc')
 +    env.Depends(date_obj, objs)
 +    objs.append(date_obj)
 +    return objs
 +
 +###################################################
 +#
 +# Define binaries.  Each different build type (debug, opt, etc.) gets
 +# a slightly different build environment.
 +#
 +###################################################
 +
 +# List of constructed environments to pass back to SConstruct
 +envList = []
 +
 +# Function to create a new build environment as clone of current
 +# environment 'env' with modified object suffix and optional stripped
 +# binary.  Additional keyword arguments are appended to corresponding
 +# build environment vars.
 +def makeEnv(label, objsfx, strip = False, **kwargs):
 +    newEnv = env.Copy(OBJSUFFIX=objsfx)
 +    newEnv.Label = label
 +    newEnv.Append(**kwargs)
 +    exe = 'm5.' + label  # final executable
 +    bin = exe + '.bin'   # executable w/o appended Python zip archive
 +    newEnv.Program(bin, make_objs(sources, newEnv))
 +    if strip:
 +        stripped_bin = bin + '.stripped'
 +        newEnv.Command(stripped_bin, bin, 'strip $SOURCE -o $TARGET')
 +        bin = stripped_bin
 +    targets = newEnv.Concat(exe, [bin, 'python/m5py.zip'])
 +    newEnv.M5Binary = targets[0]
 +    envList.append(newEnv)
 +
 +# Debug binary
 +makeEnv('debug', '.do',
 +        CCFLAGS = Split('-g3 -gdwarf-2 -O0'),
 +        CPPDEFINES = 'DEBUG')
 +
 +# Optimized binary
 +makeEnv('opt', '.o',
 +        CCFLAGS = Split('-g -O3'))
 +
 +# "Fast" binary
 +makeEnv('fast', '.fo', strip = True,
 +        CCFLAGS = Split('-O3'),
 +        CPPDEFINES = 'NDEBUG')
 +
 +# Profiled binary
 +makeEnv('prof', '.po',
 +        CCFLAGS = Split('-O3 -g -pg'),
 +        LINKFLAGS = '-pg')
 +
 +Return('envList')
index 91f8b5af15befad4a23da83c5f7dd50f839eb32d,0000000000000000000000000000000000000000..7cf68e0db350be8dc8b7d21dee0eb0689522e428
mode 100644,000000..100644
--- /dev/null
@@@ -1,158 -1,0 +1,148 @@@
-     Param<bool> bin;
-     VectorParam<string> binned_fns;
-     Param<bool> bin_int;
 +/*
 + * 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
 + * 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: Ben Nash
 + */
 +
 +/**
 + * @file
 + * Modifications for the FreeBSD kernel.
 + * Based on kern/linux/linux_system.cc.
 + *
 + */
 +
 +#include "arch/alpha/system.hh"
 +#include "arch/alpha/freebsd/system.hh"
 +#include "base/loader/symtab.hh"
 +#include "cpu/thread_context.hh"
 +#include "mem/physical.hh"
 +#include "mem/port.hh"
 +#include "arch/isa_traits.hh"
 +#include "sim/builder.hh"
 +#include "sim/byteswap.hh"
 +#include "arch/vtophys.hh"
 +
 +#define TIMER_FREQUENCY 1193180
 +
 +using namespace std;
 +using namespace AlphaISA;
 +
 +FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p)
 +    : AlphaSystem(p)
 +{
 +    /**
 +     * Any time DELAY is called just skip the function.
 +     * Shouldn't we actually emulate the delay?
 +     */
 +    skipDelayEvent = addKernelFuncEvent<SkipFuncEvent>("DELAY");
 +    skipCalibrateClocks =
 +        addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks");
 +}
 +
 +
 +FreebsdAlphaSystem::~FreebsdAlphaSystem()
 +{
 +    delete skipDelayEvent;
 +    delete skipCalibrateClocks;
 +}
 +
 +
 +void
 +FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
 +{
 +    Addr ppc_vaddr = 0;
 +    Addr timer_vaddr = 0;
 +
 +    ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg1);
 +    timer_vaddr = (Addr)tc->readIntReg(ArgumentReg2);
 +
 +    virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency);
 +    virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
 +}
 +
 +
 +void
 +FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc)
 +{
 +    SkipFuncEvent::process(tc);
 +    ((FreebsdAlphaSystem *)tc->getSystemPtr())->doCalibrateClocks(tc);
 +}
 +
 +
 +BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
 +
 +    Param<Tick> boot_cpu_frequency;
 +    SimObjectParam<PhysicalMemory *> physmem;
 +
 +    Param<string> kernel;
 +    Param<string> console;
 +    Param<string> pal;
 +
 +    Param<string> boot_osflags;
 +    Param<string> readfile;
 +    Param<unsigned int> init_param;
 +
 +    Param<uint64_t> system_type;
 +    Param<uint64_t> system_rev;
 +
-     INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
-     INIT_PARAM_DFLT(bin, "is this system to be binned", false),
-     INIT_PARAM(binned_fns, "functions to be broken down and binned"),
-     INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
 +END_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
 +
 +BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
 +
 +    INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
 +    INIT_PARAM(physmem, "phsyical memory"),
 +    INIT_PARAM(kernel, "file that contains the kernel code"),
 +    INIT_PARAM(console, "file that contains the console code"),
 +    INIT_PARAM(pal, "file that contains palcode"),
 +    INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
 +                    "a"),
 +    INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
 +    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
 +    INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
-     p->bin = bin;
-     p->binned_fns = binned_fns;
-     p->bin_int = bin_int;
++    INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
 +
 +END_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
 +
 +CREATE_SIM_OBJECT(FreebsdAlphaSystem)
 +{
 +    AlphaSystem::Params *p = new AlphaSystem::Params;
 +    p->name = getInstanceName();
 +    p->boot_cpu_frequency = boot_cpu_frequency;
 +    p->physmem = physmem;
 +    p->kernel_path = kernel;
 +    p->console_path = console;
 +    p->palcode = pal;
 +    p->boot_osflags = boot_osflags;
 +    p->init_param = init_param;
 +    p->readfile = readfile;
 +    p->system_type = system_type;
 +    p->system_rev = system_rev;
 +    return new FreebsdAlphaSystem(p);
 +}
 +
 +REGISTER_SIM_OBJECT("FreebsdAlphaSystem", FreebsdAlphaSystem)
 +
index 3e061bba8a84fab6e6d5b2437a0d7928493ed17a,0000000000000000000000000000000000000000..bb35f046dc46651774a086cd44e082f141bfcdd1
mode 100644,000000..100644
--- /dev/null
@@@ -1,273 -1,0 +1,245 @@@
-     if (params()->bin_int) {
-         intStartEvent = addPalFuncEvent<InterruptStartEvent>("sys_int_21");
-         if (!intStartEvent)
-             panic("could not find symbol: sys_int_21\n");
-         intEndEvent = addPalFuncEvent<InterruptEndEvent>("rti_to_kern");
-         if (!intEndEvent)
-             panic("could not find symbol: rti_to_kern\n");
-         intEndEvent2 = addPalFuncEvent<InterruptEndEvent>("rti_to_user");
-         if (!intEndEvent2)
-             panic("could not find symbol: rti_to_user\n");
-         intEndEvent3 = addKernelFuncEvent<InterruptEndEvent>("do_softirq");
-         if (!intEndEvent3)
-             panic("could not find symbol: do_softirq\n");
-     }
 +/*
 + * 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
 + * 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
 + *          Lisa Hsu
 + *          Nathan Binkert
 + *          Steve Reinhardt
 + */
 +
 +/**
 + * @file
 + * This code loads the linux kernel, console, pal and patches certain
 + * functions.  The symbol tables are loaded so that traces can show
 + * the executing function and we can skip functions. Various delay
 + * loops are skipped and their final values manually computed to speed
 + * up boot time.
 + */
 +
 +#include "arch/arguments.hh"
 +#include "arch/vtophys.hh"
 +#include "arch/alpha/linux/system.hh"
 +#include "arch/alpha/linux/threadinfo.hh"
 +#include "arch/alpha/system.hh"
 +#include "base/loader/symtab.hh"
 +#include "cpu/thread_context.hh"
 +#include "cpu/base.hh"
 +#include "dev/platform.hh"
 +#include "kern/linux/printk.hh"
 +#include "kern/linux/events.hh"
 +#include "mem/physical.hh"
 +#include "mem/port.hh"
 +#include "sim/builder.hh"
 +#include "sim/byteswap.hh"
 +
 +using namespace std;
 +using namespace AlphaISA;
 +using namespace Linux;
 +
 +LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
 +    : AlphaSystem(p)
 +{
 +    Addr addr = 0;
 +
 +    /**
 +     * The symbol swapper_pg_dir marks the beginning of the kernel and
 +     * the location of bootloader passed arguments
 +     */
 +    if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) {
 +        panic("Could not determine start location of kernel");
 +    }
 +
 +    /**
 +     * Since we aren't using a bootloader, we have to copy the
 +     * kernel arguments directly into the kernel's memory.
 +     */
 +    virtPort.writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
 +                params()->boot_osflags.length()+1);
 +
 +    /**
 +     * find the address of the est_cycle_freq variable and insert it
 +     * so we don't through the lengthly process of trying to
 +     * calculated it by using the PIT, RTC, etc.
 +     */
 +    if (kernelSymtab->findAddress("est_cycle_freq", addr))
 +        virtPort.write(addr, (uint64_t)(Clock::Frequency /
 +                    p->boot_cpu_frequency));
 +
 +
 +    /**
 +     * EV5 only supports 127 ASNs so we are going to tell the kernel that the
 +     * paritiuclar EV6 we have only supports 127 asns.
 +     * @todo At some point we should change ev5.hh and the palcode to support
 +     * 255 ASNs.
 +     */
 +    if (kernelSymtab->findAddress("dp264_mv", addr))
 +        virtPort.write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
 +    else
 +        panic("could not find dp264_mv\n");
 +
 +#ifndef NDEBUG
 +    kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
 +    if (!kernelPanicEvent)
 +        panic("could not find kernel symbol \'panic\'");
 +
 +#if 0
 +    kernelDieEvent = addKernelFuncEvent<BreakPCEvent>("die_if_kernel");
 +    if (!kernelDieEvent)
 +        panic("could not find kernel symbol \'die_if_kernel\'");
 +#endif
 +
 +#endif
 +
 +    /**
 +     * Any time ide_delay_50ms, calibarte_delay or
 +     * determine_cpu_caches is called just skip the
 +     * function. Currently determine_cpu_caches only is used put
 +     * information in proc, however if that changes in the future we
 +     * will have to fill in the cache size variables appropriately.
 +     */
 +
 +    skipIdeDelay50msEvent =
 +        addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms");
 +    skipDelayLoopEvent =
 +        addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay");
 +    skipCacheProbeEvent =
 +        addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches");
 +    debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
 +    idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle");
 +
 +    if (kernelSymtab->findAddress("alpha_switch_to", addr) && DTRACE(Thread)) {
 +        printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
 +                                               addr + sizeof(MachInst) * 6);
 +    } else {
 +        printThreadEvent = NULL;
 +    }
-     Param<bool> bin;
-     VectorParam<string> binned_fns;
-     Param<bool> bin_int;
 +}
 +
 +LinuxAlphaSystem::~LinuxAlphaSystem()
 +{
 +#ifndef NDEBUG
 +    delete kernelPanicEvent;
 +#endif
 +    delete skipIdeDelay50msEvent;
 +    delete skipDelayLoopEvent;
 +    delete skipCacheProbeEvent;
 +    delete debugPrintkEvent;
 +    delete idleStartEvent;
 +    delete printThreadEvent;
 +    delete intStartEvent;
 +    delete intEndEvent;
 +    delete intEndEvent2;
 +}
 +
 +
 +void
 +LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
 +{
 +    Addr addr = 0;
 +    if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
 +        Tick cpuFreq = tc->getCpuPtr()->frequency();
 +        Tick intrFreq = platform->intrFrequency();
 +        VirtualPort *vp;
 +
 +        vp = tc->getVirtPort();
 +        vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
 +        tc->delVirtPort(vp);
 +    }
 +}
 +
 +
 +void
 +LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc)
 +{
 +    SkipFuncEvent::process(tc);
 +    // calculate and set loops_per_jiffy
 +    ((LinuxAlphaSystem *)tc->getSystemPtr())->setDelayLoop(tc);
 +}
 +
 +void
 +LinuxAlphaSystem::PrintThreadInfo::process(ThreadContext *tc)
 +{
 +    Linux::ThreadInfo ti(tc);
 +
 +    DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n",
 +            ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart());
 +}
 +
 +
 +BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
 +
 +    Param<Tick> boot_cpu_frequency;
 +    SimObjectParam<PhysicalMemory *> physmem;
 +
 +    Param<string> kernel;
 +    Param<string> console;
 +    Param<string> pal;
 +
 +    Param<string> boot_osflags;
 +    Param<string> readfile;
 +    Param<unsigned int> init_param;
 +
 +    Param<uint64_t> system_type;
 +    Param<uint64_t> system_rev;
 +
-     INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
-     INIT_PARAM_DFLT(bin, "is this system to be binned", false),
-     INIT_PARAM(binned_fns, "functions to be broken down and binned"),
-     INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
 +END_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
 +
 +BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
 +
 +    INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
 +    INIT_PARAM(physmem, "phsyical memory"),
 +    INIT_PARAM(kernel, "file that contains the kernel code"),
 +    INIT_PARAM(console, "file that contains the console code"),
 +    INIT_PARAM(pal, "file that contains palcode"),
 +    INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
 +                    "a"),
 +    INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
 +    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
 +    INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
-     p->bin = bin;
-     p->binned_fns = binned_fns;
-     p->bin_int = bin_int;
++    INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
 +
 +END_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
 +
 +CREATE_SIM_OBJECT(LinuxAlphaSystem)
 +{
 +    AlphaSystem::Params *p = new AlphaSystem::Params;
 +    p->name = getInstanceName();
 +    p->boot_cpu_frequency = boot_cpu_frequency;
 +    p->physmem = physmem;
 +    p->kernel_path = kernel;
 +    p->console_path = console;
 +    p->palcode = pal;
 +    p->boot_osflags = boot_osflags;
 +    p->init_param = init_param;
 +    p->readfile = readfile;
 +    p->system_type = system_type;
 +    p->system_rev = system_rev;
 +    return new LinuxAlphaSystem(p);
 +}
 +
 +REGISTER_SIM_OBJECT("LinuxAlphaSystem", LinuxAlphaSystem)
 +
index c03586ac5063a12145134dc6234a42eccf3f837c,0000000000000000000000000000000000000000..6921ba820cb67b69ca8284dc6e358b12bd157dc4
mode 100644,000000..100644
--- /dev/null
@@@ -1,149 -1,0 +1,137 @@@
-  * This class contains linux specific system code (Loading, Events, Binning).
 +/*
 + * 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: Ali Saidi
 + *          Lisa Hsu
 + *          Nathan Binkert
 + */
 +
 +#ifndef __ARCH_ALPHA_LINUX_SYSTEM_HH__
 +#define __ARCH_ALPHA_LINUX_SYSTEM_HH__
 +
 +class ThreadContext;
 +
 +class BreakPCEvent;
 +class IdleStartEvent;
 +
 +#include "arch/alpha/system.hh"
 +#include "kern/linux/events.hh"
 +
 +using namespace AlphaISA;
 +using namespace Linux;
 +
 +/**
-     /**
-      * Event to bin Interrupts seperately from kernel code
-      */
-     InterruptStartEvent *intStartEvent;
-     /**
-      * Event to bin Interrupts seperately from kernel code
-      */
-     InterruptEndEvent *intEndEvent;
-     InterruptEndEvent *intEndEvent2;
-     InterruptEndEvent *intEndEvent3;
++ * This class contains linux specific system code (Loading, Events).
 + * It points to objects that are the system binaries to load and patches them
 + * appropriately to work in simulator.
 + */
 +class LinuxAlphaSystem : public AlphaSystem
 +{
 +  private:
 +    class SkipDelayLoopEvent : public SkipFuncEvent
 +    {
 +      public:
 +        SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr)
 +            : SkipFuncEvent(q, desc, addr) {}
 +        virtual void process(ThreadContext *tc);
 +    };
 +
 +    class PrintThreadInfo : public PCEvent
 +    {
 +      public:
 +        PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr)
 +            : PCEvent(q, desc, addr) {}
 +        virtual void process(ThreadContext *tc);
 +    };
 +
 +
 +    /**
 +     * Addresses defining where the kernel bootloader places various
 +     * elements.  Details found in include/asm-alpha/system.h
 +     */
 +    Addr KernelStart; // Lookup the symbol swapper_pg_dir
 +
 +  public:
 +    Addr InitStack() const { return KernelStart + 0x02000; }
 +    Addr EmptyPGT() const  { return KernelStart + 0x04000; }
 +    Addr EmptyPGE() const  { return KernelStart + 0x08000; }
 +    Addr ZeroPGE() const   { return KernelStart + 0x0A000; }
 +    Addr StartAddr() const { return KernelStart + 0x10000; }
 +
 +    Addr Param() const { return ZeroPGE() + 0x0; }
 +    Addr CommandLine() const { return Param() + 0x0; }
 +    Addr InitrdStart() const { return Param() + 0x100; }
 +    Addr InitrdSize() const { return Param() + 0x108; }
 +    static const int CommandLineSize = 256;
 +
 +  private:
 +#ifndef NDEBUG
 +    /** Event to halt the simulator if the kernel calls panic()  */
 +    BreakPCEvent *kernelPanicEvent;
 +
 +    /** Event to halt the simulator if the kernel calls die_if_kernel  */
 +    BreakPCEvent *kernelDieEvent;
 +#endif
 +
 +    /**
 +     * Event to skip determine_cpu_caches() because we don't support
 +     * the IPRs that the code can access to figure out cache sizes
 +     */
 +    SkipFuncEvent *skipCacheProbeEvent;
 +
 +    /** PC based event to skip the ide_delay_50ms() call */
 +    SkipFuncEvent *skipIdeDelay50msEvent;
 +
 +    /**
 +     * PC based event to skip the dprink() call and emulate its
 +     * functionality
 +     */
 +    DebugPrintkEvent *debugPrintkEvent;
 +
 +    /**
 +     * Skip calculate_delay_loop() rather than waiting for this to be
 +     * calculated
 +     */
 +    SkipDelayLoopEvent *skipDelayLoopEvent;
 +
 +    /**
 +     * Event to print information about thread switches if the trace flag
 +     * Thread is set
 +     */
 +    PrintThreadInfo *printThreadEvent;
 +
 +    /** Grab the PCBB of the idle process when it starts */
 +    IdleStartEvent *idleStartEvent;
 +
 +  public:
 +    LinuxAlphaSystem(Params *p);
 +    ~LinuxAlphaSystem();
 +
 +    void setDelayLoop(ThreadContext *tc);
 +};
 +
 +#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__
index a68e440b0a7b1ce311389bcb471f522037bf01ad,0000000000000000000000000000000000000000..3aaba7d58c9f14d8f3ba930056b16e83839022b5
mode 100644,000000..100644
--- /dev/null
@@@ -1,282 -1,0 +1,272 @@@
-     Param<bool> bin;
-     VectorParam<std::string> binned_fns;
-     Param<bool> bin_int;
 +/*
 + * 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
 + * 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
 + */
 +
 +#include "arch/alpha/ev5.hh"
 +#include "arch/alpha/system.hh"
 +#include "arch/vtophys.hh"
 +#include "base/remote_gdb.hh"
 +#include "base/loader/object_file.hh"
 +#include "base/loader/symtab.hh"
 +#include "base/trace.hh"
 +#include "mem/physical.hh"
 +#include "sim/byteswap.hh"
 +#include "sim/builder.hh"
 +
 +
 +using namespace LittleEndianGuest;
 +
 +AlphaSystem::AlphaSystem(Params *p)
 +    : System(p)
 +{
 +    consoleSymtab = new SymbolTable;
 +    palSymtab = new SymbolTable;
 +
 +
 +    /**
 +     * Load the pal, and console code into memory
 +     */
 +    // Load Console Code
 +    console = createObjectFile(params()->console_path);
 +    if (console == NULL)
 +        fatal("Could not load console file %s", params()->console_path);
 +
 +    // Load pal file
 +    pal = createObjectFile(params()->palcode);
 +    if (pal == NULL)
 +        fatal("Could not load PALcode file %s", params()->palcode);
 +
 +
 +    // Load program sections into memory
 +    pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
 +    console->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
 +
 +    // load symbols
 +    if (!console->loadGlobalSymbols(consoleSymtab))
 +        panic("could not load console symbols\n");
 +
 +    if (!pal->loadGlobalSymbols(palSymtab))
 +        panic("could not load pal symbols\n");
 +
 +    if (!pal->loadLocalSymbols(palSymtab))
 +        panic("could not load pal symbols\n");
 +
 +    if (!console->loadGlobalSymbols(debugSymbolTable))
 +        panic("could not load console symbols\n");
 +
 +    if (!pal->loadGlobalSymbols(debugSymbolTable))
 +        panic("could not load pal symbols\n");
 +
 +    if (!pal->loadLocalSymbols(debugSymbolTable))
 +        panic("could not load pal symbols\n");
 +
 +     Addr addr = 0;
 +#ifndef NDEBUG
 +    consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
 +#endif
 +
 +    /**
 +     * Copy the osflags (kernel arguments) into the consoles
 +     * memory. (Presently Linux does not use the console service
 +     * routine to get these command line arguments, but Tru64 and
 +     * others do.)
 +     */
 +    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
 +        virtPort.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
 +                strlen(params()->boot_osflags.c_str()));
 +    }
 +
 +    /**
 +     * Set the hardware reset parameter block system type and revision
 +     * information to Tsunami.
 +     */
 +    if (consoleSymtab->findAddress("m5_rpb", addr)) {
 +        uint64_t data;
 +        data = htog(params()->system_type);
 +        virtPort.write(addr+0x50, data);
 +        data = htog(params()->system_rev);
 +        virtPort.write(addr+0x58, data);
 +    } else
 +        panic("could not find hwrpb\n");
 +
 +}
 +
 +AlphaSystem::~AlphaSystem()
 +{
 +    delete consoleSymtab;
 +    delete console;
 +    delete pal;
 +#ifdef DEBUG
 +    delete consolePanicEvent;
 +#endif
 +}
 +
 +/**
 + * This function fixes up addresses that are used to match PCs for
 + * hooking simulator events on to target function executions.
 + *
 + * Alpha binaries may have multiple global offset table (GOT)
 + * sections.  A function that uses the GOT starts with a
 + * two-instruction prolog which sets the global pointer (gp == r29) to
 + * the appropriate GOT section.  The proper gp value is calculated
 + * based on the function address, which must be passed by the caller
 + * in the procedure value register (pv aka t12 == r27).  This sequence
 + * looks like the following:
 + *
 + *                    opcode Ra Rb offset
 + *    ldah gp,X(pv)     09   29 27   X
 + *    lda  gp,Y(gp)     08   29 29   Y
 + *
 + * for some constant offsets X and Y.  The catch is that the linker
 + * (or maybe even the compiler, I'm not sure) may recognize that the
 + * caller and callee are using the same GOT section, making this
 + * prolog redundant, and modify the call target to skip these
 + * instructions.  If we check for execution of the first instruction
 + * of a function (the one the symbol points to) to detect when to skip
 + * it, we'll miss all these modified calls.  It might work to
 + * unconditionally check for the third instruction, but not all
 + * functions have this prolog, and there's some chance that those
 + * first two instructions could have undesired consequences.  So we do
 + * the Right Thing and pattern-match the first two instructions of the
 + * function to decide where to patch.
 + *
 + * Eventually this code should be moved into an ISA-specific file.
 + */
 +Addr
 +AlphaSystem::fixFuncEventAddr(Addr addr)
 +{
 +    // mask for just the opcode, Ra, and Rb fields (not the offset)
 +    const uint32_t inst_mask = 0xffff0000;
 +    // ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27
 +    const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16);
 +    // lda  gp,Y(gp): opcode 8, Ra = 29, rb = 29
 +    const uint32_t gp_lda_pattern  = (8 << 26) | (29 << 21) | (29 << 16);
 +
 +    uint32_t i1 = virtPort.read<uint32_t>(addr);
 +    uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(AlphaISA::MachInst));
 +
 +    if ((i1 & inst_mask) == gp_ldah_pattern &&
 +        (i2 & inst_mask) == gp_lda_pattern) {
 +        Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst);
 +        DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr);
 +        return new_addr;
 +    } else {
 +        return addr;
 +    }
 +}
 +
 +
 +void
 +AlphaSystem::setAlphaAccess(Addr access)
 +{
 +    Addr addr = 0;
 +    if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
 +        virtPort.write(addr, htog(EV5::Phys2K0Seg(access)));
 +    } else
 +        panic("could not find m5AlphaAccess\n");
 +}
 +
 +bool
 +AlphaSystem::breakpoint()
 +{
 +    return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
 +}
 +
 +void
 +AlphaSystem::serialize(std::ostream &os)
 +{
 +    System::serialize(os);
 +    consoleSymtab->serialize("console_symtab", os);
 +    palSymtab->serialize("pal_symtab", os);
 +}
 +
 +
 +void
 +AlphaSystem::unserialize(Checkpoint *cp, const std::string &section)
 +{
 +    System::unserialize(cp,section);
 +    consoleSymtab->unserialize("console_symtab", cp, section);
 +    palSymtab->unserialize("pal_symtab", cp, section);
 +}
 +
 +
 +BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
 +
 +    Param<Tick> boot_cpu_frequency;
 +    SimObjectParam<PhysicalMemory *> physmem;
 +
 +    Param<std::string> kernel;
 +    Param<std::string> console;
 +    Param<std::string> pal;
 +
 +    Param<std::string> boot_osflags;
 +    Param<std::string> readfile;
 +    Param<unsigned int> init_param;
 +
 +    Param<uint64_t> system_type;
 +    Param<uint64_t> system_rev;
 +
-     INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
-     INIT_PARAM_DFLT(bin, "is this system to be binned", false),
-     INIT_PARAM(binned_fns, "functions to be broken down and binned"),
-     INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
 +END_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
 +
 +BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
 +
 +    INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
 +    INIT_PARAM(physmem, "phsyical memory"),
 +    INIT_PARAM(kernel, "file that contains the kernel code"),
 +    INIT_PARAM(console, "file that contains the console code"),
 +    INIT_PARAM(pal, "file that contains palcode"),
 +    INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
 +                    "a"),
 +    INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
 +    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
 +    INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
-     p->bin = bin;
-     p->binned_fns = binned_fns;
-     p->bin_int = bin_int;
++    INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
 +
 +END_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
 +
 +CREATE_SIM_OBJECT(AlphaSystem)
 +{
 +    AlphaSystem::Params *p = new AlphaSystem::Params;
 +    p->name = getInstanceName();
 +    p->boot_cpu_frequency = boot_cpu_frequency;
 +    p->physmem = physmem;
 +    p->kernel_path = kernel;
 +    p->console_path = console;
 +    p->palcode = pal;
 +    p->boot_osflags = boot_osflags;
 +    p->init_param = init_param;
 +    p->readfile = readfile;
 +    p->system_type = system_type;
 +    p->system_rev = system_rev;
 +    return new AlphaSystem(p);
 +}
 +
 +REGISTER_SIM_OBJECT("AlphaSystem", AlphaSystem)
 +
 +
index 8d9a53273d099c50b39fb7723fcf6c160153bd37,0000000000000000000000000000000000000000..6c0edc1eecf0d18dfe5541daa2b9010ba3e449dd
mode 100644,000000..100644
--- /dev/null
@@@ -1,154 -1,0 +1,146 @@@
-     Param<bool> bin;
-     VectorParam<string> binned_fns;
 +/*
 + * Copyright (c) 2003-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
 + *          Lisa Hsu
 + */
 +
 +#include "arch/alpha/tru64/system.hh"
 +#include "arch/isa_traits.hh"
 +#include "arch/vtophys.hh"
 +#include "base/loader/symtab.hh"
 +#include "base/trace.hh"
 +#include "cpu/base.hh"
 +#include "cpu/thread_context.hh"
 +#include "kern/tru64/tru64_events.hh"
 +#include "kern/system_events.hh"
 +#include "mem/physical.hh"
 +#include "mem/port.hh"
 +#include "sim/builder.hh"
 +
 +using namespace std;
 +
 +Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
 +    : AlphaSystem(p)
 +{
 +    Addr addr = 0;
 +    if (kernelSymtab->findAddress("enable_async_printf", addr)) {
 +        virtPort.write(addr, (uint32_t)0);
 +    }
 +
 +#ifdef DEBUG
 +    kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
 +    if (!kernelPanicEvent)
 +        panic("could not find kernel symbol \'panic\'");
 +#endif
 +
 +    badaddrEvent = addKernelFuncEvent<BadAddrEvent>("badaddr");
 +    if (!badaddrEvent)
 +        panic("could not find kernel symbol \'badaddr\'");
 +
 +    skipPowerStateEvent =
 +        addKernelFuncEvent<SkipFuncEvent>("tl_v48_capture_power_state");
 +    skipScavengeBootEvent =
 +        addKernelFuncEvent<SkipFuncEvent>("pmap_scavenge_boot");
 +
 +#if TRACING_ON
 +    printfEvent = addKernelFuncEvent<PrintfEvent>("printf");
 +    debugPrintfEvent = addKernelFuncEvent<DebugPrintfEvent>("m5printf");
 +    debugPrintfrEvent = addKernelFuncEvent<DebugPrintfrEvent>("m5printfr");
 +    dumpMbufEvent = addKernelFuncEvent<DumpMbufEvent>("m5_dump_mbuf");
 +#endif
 +}
 +
 +Tru64AlphaSystem::~Tru64AlphaSystem()
 +{
 +#ifdef DEBUG
 +    delete kernelPanicEvent;
 +#endif
 +    delete badaddrEvent;
 +    delete skipPowerStateEvent;
 +    delete skipScavengeBootEvent;
 +#if TRACING_ON
 +    delete printfEvent;
 +    delete debugPrintfEvent;
 +    delete debugPrintfrEvent;
 +    delete dumpMbufEvent;
 +#endif
 +}
 +
 +BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
 +
 +    Param<Tick> boot_cpu_frequency;
 +    SimObjectParam<PhysicalMemory *> physmem;
 +
 +    Param<string> kernel;
 +    Param<string> console;
 +    Param<string> pal;
 +
 +    Param<string> boot_osflags;
 +    Param<string> readfile;
 +    Param<unsigned int> init_param;
 +
 +    Param<uint64_t> system_type;
 +    Param<uint64_t> system_rev;
 +
-     INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1),
-     INIT_PARAM_DFLT(bin, "is this system to be binned", false),
-     INIT_PARAM(binned_fns, "functions to be broken down and binned")
 +END_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
 +
 +BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
 +
 +    INIT_PARAM(boot_cpu_frequency, "frequency of the boot cpu"),
 +    INIT_PARAM(physmem, "phsyical memory"),
 +    INIT_PARAM(kernel, "file that contains the kernel code"),
 +    INIT_PARAM(console, "file that contains the console code"),
 +    INIT_PARAM(pal, "file that contains palcode"),
 +    INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
 +                    "a"),
 +    INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
 +    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
 +    INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 12),
-     p->bin = bin;
-     p->binned_fns = binned_fns;
-     p->bin_int = false;
++    INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1)
 +
 +END_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
 +
 +CREATE_SIM_OBJECT(Tru64AlphaSystem)
 +{
 +    AlphaSystem::Params *p = new AlphaSystem::Params;
 +    p->name = getInstanceName();
 +    p->boot_cpu_frequency = boot_cpu_frequency;
 +    p->physmem = physmem;
 +    p->kernel_path = kernel;
 +    p->console_path = console;
 +    p->palcode = pal;
 +    p->boot_osflags = boot_osflags;
 +    p->init_param = init_param;
 +    p->readfile = readfile;
 +    p->system_type = system_type;
 +    p->system_rev = system_rev;
 +
 +    return new Tru64AlphaSystem(p);
 +}
 +
 +REGISTER_SIM_OBJECT("Tru64AlphaSystem", Tru64AlphaSystem)
index 03c6b51964a2a96489e6c69816c85370b89f8d5a,0000000000000000000000000000000000000000..2acef83c5a3dee894448544235434d6c199fa60b
mode 100644,000000..100644
--- /dev/null
@@@ -1,358 -1,0 +1,292 @@@
- #include "config/stats_binning.hh"
 +/*
 + * Copyright (c) 2003-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 <iomanip>
 +#include <fstream>
 +#include <list>
 +#include <map>
 +#include <string>
 +
 +#include "base/callback.hh"
 +#include "base/cprintf.hh"
 +#include "base/hostinfo.hh"
 +#include "base/misc.hh"
 +#include "base/statistics.hh"
 +#include "base/str.hh"
 +#include "base/time.hh"
 +#include "base/trace.hh"
 +#include "base/stats/statdb.hh"
- bool
- FormulaBase::binned() const
- {
-     return root && root->binned();
- }
 +
 +using namespace std;
 +
 +namespace Stats {
 +
 +StatData *
 +DataAccess::find() const
 +{
 +    return Database::find(const_cast<void *>((const void *)this));
 +}
 +
 +const StatData *
 +getStatData(const void *stat)
 +{
 +    return Database::find(const_cast<void *>(stat));
 +}
 +
 +void
 +DataAccess::map(StatData *data)
 +{
 +    Database::regStat(this, data);
 +}
 +
 +StatData *
 +DataAccess::statData()
 +{
 +    StatData *ptr = find();
 +    assert(ptr);
 +    return ptr;
 +}
 +
 +const StatData *
 +DataAccess::statData() const
 +{
 +    const StatData *ptr = find();
 +    assert(ptr);
 +    return ptr;
 +}
 +
 +void
 +DataAccess::setInit()
 +{
 +    statData()->flags |= init;
 +}
 +
 +void
 +DataAccess::setPrint()
 +{
 +    Database::regPrint(this);
 +}
 +
 +StatData::StatData()
 +    : flags(none), precision(-1), prereq(0)
 +{
 +    static int count = 0;
 +    id = count++;
 +}
 +
 +StatData::~StatData()
 +{
 +}
 +
 +bool
 +StatData::less(StatData *stat1, StatData *stat2)
 +{
 +    const string &name1 = stat1->name;
 +    const string &name2 = stat2->name;
 +
 +    vector<string> v1;
 +    vector<string> v2;
 +
 +    tokenize(v1, name1, '.');
 +    tokenize(v2, name2, '.');
 +
 +    int last = min(v1.size(), v2.size()) - 1;
 +    for (int i = 0; i < last; ++i)
 +        if (v1[i] != v2[i])
 +            return v1[i] < v2[i];
 +
 +    // Special compare for last element.
 +    if (v1[last] == v2[last])
 +        return v1.size() < v2.size();
 +    else
 +        return v1[last] < v2[last];
 +
 +    return false;
 +}
 +
 +bool
 +StatData::baseCheck() const
 +{
 +    if (!(flags & init)) {
 +#ifdef DEBUG
 +        cprintf("this is stat number %d\n", id);
 +#endif
 +        panic("Not all stats have been initialized");
 +        return false;
 +    }
 +
 +    if ((flags & print) && name.empty()) {
 +        panic("all printable stats must be named");
 +        return false;
 +    }
 +
 +    return true;
 +}
 +
 +
 +void
 +FormulaBase::result(VResult &vec) const
 +{
 +    if (root)
 +        vec = root->result();
 +}
 +
 +Result
 +FormulaBase::total() const
 +{
 +    return root ? root->total() : 0.0;
 +}
 +
 +size_t
 +FormulaBase::size() const
 +{
 +    if (!root)
 +        return 0;
 +    else
 +        return root->size();
 +}
 +
- MainBin::MainBin(const string &name)
-     : _name(name), mem(NULL), memsize(-1)
- {
-     Database::regBin(this, name);
- }
- MainBin::~MainBin()
- {
-     if (mem)
-         delete [] mem;
- }
- char *
- MainBin::memory(off_t off)
- {
-     if (memsize == -1)
-         memsize = ceilPow2((size_t) offset());
-     if (!mem) {
-         mem = new char[memsize];
-         memset(mem, 0, memsize);
-     }
-     assert(offset() <= size());
-     return mem + off;
- }
 +void
 +FormulaBase::reset()
 +{
 +}
 +
 +bool
 +FormulaBase::zero() const
 +{
 +    VResult vec;
 +    result(vec);
 +    for (int i = 0; i < vec.size(); ++i)
 +        if (vec[i] != 0.0)
 +            return false;
 +    return true;
 +}
 +
 +void
 +FormulaBase::update(StatData *)
 +{
 +}
 +
 +string
 +FormulaBase::str() const
 +{
 +    return root ? root->str() : "";
 +}
 +
 +Formula::Formula()
 +{
 +    setInit();
 +}
 +
 +Formula::Formula(Temp r)
 +{
 +    root = r;
 +    assert(size());
 +}
 +
 +const Formula &
 +Formula::operator=(Temp r)
 +{
 +    assert(!root && "Can't change formulas");
 +    root = r;
 +    assert(size());
 +    return *this;
 +}
 +
 +const Formula &
 +Formula::operator+=(Temp r)
 +{
 +    if (root)
 +        root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
 +    else
 +        root = r;
 +    assert(size());
 +    return *this;
 +}
 +
- #if STATS_BINNING
-     if (MainBin::curBin() == NULL) {
-         static MainBin mainBin("main bin");
-         mainBin.activate();
-     }
- #endif
 +void
 +check()
 +{
 +    typedef Database::stat_list_t::iterator iter_t;
 +
 +    iter_t i, end = Database::stats().end();
 +    for (i = Database::stats().begin(); i != end; ++i) {
 +        StatData *data = *i;
 +        assert(data);
 +        if (!data->check() || !data->baseCheck())
 +            panic("stat check failed for %s\n", data->name);
 +    }
 +
 +    int j = 0;
 +    for (i = Database::stats().begin(); i != end; ++i) {
 +        StatData *data = *i;
 +        if (!(data->flags & print))
 +            data->name = "__Stat" + to_string(j++);
 +    }
 +
 +    Database::stats().sort(StatData::less);
 +
-     // reset non-binned stats
 +    if (i == end)
 +        return;
 +
 +    iter_t last = i;
 +    ++i;
 +
 +    for (i = Database::stats().begin(); i != end; ++i) {
 +        if ((*i)->name == (*last)->name)
 +            panic("same name used twice! name=%s\n", (*i)->name);
 +
 +        last = i;
 +    }
 +}
 +
 +CallbackQueue resetQueue;
 +
 +void
 +reset()
 +{
-         if (!data->binned())
-             data->reset();
 +    Database::stat_list_t::iterator i = Database::stats().begin();
 +    Database::stat_list_t::iterator end = Database::stats().end();
 +    while (i != end) {
 +        StatData *data = *i;
-     // save the bin so we can go back to where we were
-     MainBin *orig = MainBin::curBin();
-     // reset binned stats
-     Database::bin_list_t::iterator bi = Database::bins().begin();
-     Database::bin_list_t::iterator be = Database::bins().end();
-     while (bi != be) {
-         MainBin *bin = *bi;
-         bin->activate();
-         i = Database::stats().begin();
-         while (i != end) {
-             StatData *data = *i;
-             if (data->binned())
-                 data->reset();
-             ++i;
-         }
-         ++bi;
-     }
-     // restore bin
-     MainBin::curBin() = orig;
++        data->reset();
 +        ++i;
 +    }
 +
 +    resetQueue.process();
 +}
 +
 +void
 +registerResetCallback(Callback *cb)
 +{
 +    resetQueue.add(cb);
 +}
 +
 +/* namespace Stats */ }
index 84a3230714ebdc5acc44b7ec37bb2d404053e333,0000000000000000000000000000000000000000..59f219c07c7f7d5090994a23c4e7d3cd169925d9
mode 100644,000000..100644
--- /dev/null
@@@ -1,2899 -1,0 +1,2887 @@@
- #include "base/stats/bin.hh"
 +/*
 + * Copyright (c) 2003-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
 + *          Erik Hallnor
 + */
 +
 +/** @file
 + * Declaration of Statistics objects.
 + */
 +
 +/**
 +* @todo
 +*
 +* Generalized N-dimensinal vector
 +* documentation
 +* key stats
 +* interval stats
 +*   -- these both can use the same function that prints out a
 +*   specific set of stats
 +* VectorStandardDeviation totals
 +* Document Namespaces
 +*/
 +#ifndef __BASE_STATISTICS_HH__
 +#define __BASE_STATISTICS_HH__
 +
 +#include <algorithm>
 +#include <cassert>
 +#include <cmath>
 +#include <functional>
 +#include <iosfwd>
 +#include <string>
 +#include <vector>
 +
 +#include "base/cprintf.hh"
 +#include "base/intmath.hh"
 +#include "base/refcnt.hh"
 +#include "base/str.hh"
- #include "config/stats_binning.hh"
 +#include "base/stats/flags.hh"
 +#include "base/stats/visit.hh"
 +#include "base/stats/types.hh"
-     /**
-      * @return true if the stat is binned.
-      */
-     virtual bool binned() const = 0;
 +#include "sim/host.hh"
 +
 +class Callback;
 +
 +/** The current simulated cycle. */
 +extern Tick curTick;
 +
 +/* A namespace for all of the Statistics */
 +namespace Stats {
 +
 +/* Contains the statistic implementation details */
 +//////////////////////////////////////////////////////////////////////
 +//
 +// Statistics Framework Base classes
 +//
 +//////////////////////////////////////////////////////////////////////
 +struct StatData
 +{
 +    /** The name of the stat. */
 +    std::string name;
 +    /** The description of the stat. */
 +    std::string desc;
 +    /** The formatting flags. */
 +    StatFlags flags;
 +    /** The display precision. */
 +    int precision;
 +    /** A pointer to a prerequisite Stat. */
 +    const StatData *prereq;
 +    /**
 +     * A unique stat ID for each stat in the simulator.
 +     * Can be used externally for lookups as well as for debugging.
 +     */
 +    int id;
 +
 +    StatData();
 +    virtual ~StatData();
 +
-     virtual bool binned() const { return s.binned(); }
 +    /**
 +     * Reset the corresponding stat to the default state.
 +     */
 +    virtual void reset() = 0;
 +
 +    /**
 +     * @return true if this stat has a value and satisfies its
 +     * requirement as a prereq
 +     */
 +    virtual bool zero() const = 0;
 +
 +    /**
 +     * Check that this stat has been set up properly and is ready for
 +     * use
 +     * @return true for success
 +     */
 +    virtual bool check() const = 0;
 +    bool baseCheck() const;
 +
 +    /**
 +     * Visitor entry for outputing statistics data
 +     */
 +    virtual void visit(Visit &visitor) = 0;
 +
 +    /**
 +     * Checks if the first stat's name is alphabetically less than the second.
 +     * This function breaks names up at periods and considers each subname
 +     * separately.
 +     * @param stat1 The first stat.
 +     * @param stat2 The second stat.
 +     * @return stat1's name is alphabetically before stat2's
 +     */
 +    static bool less(StatData *stat1, StatData *stat2);
 +};
 +
 +class ScalarData : public StatData
 +{
 +  public:
 +    virtual Counter value() const = 0;
 +    virtual Result result() const = 0;
 +    virtual Result total() const = 0;
 +    virtual void visit(Visit &visitor) { visitor.visit(*this); }
 +};
 +
 +template <class Stat>
 +class ScalarStatData : public ScalarData
 +{
 +  protected:
 +    Stat &s;
 +
 +  public:
 +    ScalarStatData(Stat &stat) : s(stat) {}
 +
-     virtual bool binned() const { return s.binned(); }
 +    virtual bool check() const { return s.check(); }
 +    virtual Counter value() const { return s.value(); }
 +    virtual Result result() const { return s.result(); }
 +    virtual Result total() const { return s.total(); }
 +    virtual void reset() { s.reset(); }
 +    virtual bool zero() const { return s.zero(); }
 +};
 +
 +struct VectorData : public StatData
 +{
 +    /** Names and descriptions of subfields. */
 +    mutable std::vector<std::string> subnames;
 +    mutable std::vector<std::string> subdescs;
 +
 +    virtual size_t size() const  = 0;
 +    virtual const VCounter &value() const = 0;
 +    virtual const VResult &result() const = 0;
 +    virtual Result total() const  = 0;
 +    void update()
 +    {
 +        if (!subnames.empty()) {
 +            int s = size();
 +            if (subnames.size() < s)
 +                subnames.resize(s);
 +
 +            if (subdescs.size() < s)
 +                subdescs.resize(s);
 +        }
 +    }
 +};
 +
 +template <class Stat>
 +class VectorStatData : public VectorData
 +{
 +  protected:
 +    Stat &s;
 +    mutable VCounter cvec;
 +    mutable VResult rvec;
 +
 +  public:
 +    VectorStatData(Stat &stat) : s(stat) {}
 +
-     virtual bool binned() const { return s.binned(); }
 +    virtual bool check() const { return s.check(); }
 +    virtual bool zero() const { return s.zero(); }
 +    virtual void reset() { s.reset(); }
 +
 +    virtual size_t size() const { return s.size(); }
 +    virtual VCounter &value() const
 +    {
 +        s.value(cvec);
 +        return cvec;
 +    }
 +    virtual const VResult &result() const
 +    {
 +        s.result(rvec);
 +        return rvec;
 +    }
 +    virtual Result total() const { return s.total(); }
 +    virtual void visit(Visit &visitor)
 +    {
 +        update();
 +        s.update(this);
 +        visitor.visit(*this);
 +    }
 +};
 +
 +struct DistDataData
 +{
 +    Counter min_val;
 +    Counter max_val;
 +    Counter underflow;
 +    Counter overflow;
 +    VCounter cvec;
 +    Counter sum;
 +    Counter squares;
 +    Counter samples;
 +
 +    Counter min;
 +    Counter max;
 +    Counter bucket_size;
 +    int size;
 +    bool fancy;
 +};
 +
 +struct DistData : public StatData
 +{
 +    /** Local storage for the entry values, used for printing. */
 +    DistDataData data;
 +};
 +
 +template <class Stat>
 +class DistStatData : public DistData
 +{
 +  protected:
 +    Stat &s;
 +
 +  public:
 +    DistStatData(Stat &stat) : s(stat) {}
 +
-     typedef typename Stat::bin_t bin_t;
 +    virtual bool check() const { return s.check(); }
 +    virtual void reset() { s.reset(); }
 +    virtual bool zero() const { return s.zero(); }
 +    virtual void visit(Visit &visitor)
 +    {
 +        s.update(this);
 +        visitor.visit(*this);
 +    }
 +};
 +
 +struct VectorDistData : public StatData
 +{
 +    std::vector<DistDataData> data;
 +
 +   /** Names and descriptions of subfields. */
 +    mutable std::vector<std::string> subnames;
 +    mutable std::vector<std::string> subdescs;
 +
 +    /** Local storage for the entry values, used for printing. */
 +    mutable VResult rvec;
 +
 +    virtual size_t size() const = 0;
 +    void update()
 +    {
 +        int s = size();
 +        if (subnames.size() < s)
 +            subnames.resize(s);
 +
 +        if (subdescs.size() < s)
 +            subdescs.resize(s);
 +    }
 +};
 +
 +template <class Stat>
 +class VectorDistStatData : public VectorDistData
 +{
 +  protected:
 +    Stat &s;
-     virtual bool binned() const { return bin_t::binned; }
 +
 +  public:
 +    VectorDistStatData(Stat &stat) : s(stat) {}
 +
-     typedef typename Stat::bin_t bin_t;
 +    virtual bool check() const { return s.check(); }
 +    virtual void reset() { s.reset(); }
 +    virtual size_t size() const { return s.size(); }
 +    virtual bool zero() const { return s.zero(); }
 +    virtual void visit(Visit &visitor)
 +    {
 +        update();
 +        s.update(this);
 +        visitor.visit(*this);
 +    }
 +};
 +
 +struct Vector2dData : public StatData
 +{
 +    /** Names and descriptions of subfields. */
 +    std::vector<std::string> subnames;
 +    std::vector<std::string> subdescs;
 +    std::vector<std::string> y_subnames;
 +
 +    /** Local storage for the entry values, used for printing. */
 +    mutable VCounter cvec;
 +    mutable int x;
 +    mutable int y;
 +
 +    void update()
 +    {
 +        if (subnames.size() < x)
 +            subnames.resize(x);
 +    }
 +};
 +
 +template <class Stat>
 +class Vector2dStatData : public Vector2dData
 +{
 +  protected:
 +    Stat &s;
-     virtual bool binned() const { return bin_t::binned; }
 +
 +  public:
 +    Vector2dStatData(Stat &stat) : s(stat) {}
 +
 +    virtual bool check() const { return s.check(); }
 +    virtual void reset() { s.reset(); }
 +    virtual bool zero() const { return s.zero(); }
 +    virtual void visit(Visit &visitor)
 +    {
 +        update();
 +        s.update(this);
 +        visitor.visit(*this);
 +    }
 +};
 +
-  * @todo add lateny to the stat and fix binning.
 +class DataAccess
 +{
 +  protected:
 +    StatData *find() const;
 +    void map(StatData *data);
 +
 +    StatData *statData();
 +    const StatData *statData() const;
 +
 +    void setInit();
 +    void setPrint();
 +};
 +
 +template <class Parent, class Child, template <class> class Data>
 +class Wrap : public Child
 +{
 +  protected:
 +    Parent &self() { return *reinterpret_cast<Parent *>(this); }
 +
 +  protected:
 +    Data<Child> *statData()
 +    {
 +        StatData *__data = DataAccess::statData();
 +        Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
 +        assert(ptr);
 +        return ptr;
 +    }
 +
 +  public:
 +    const Data<Child> *statData() const
 +    {
 +        const StatData *__data = DataAccess::statData();
 +        const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
 +        assert(ptr);
 +        return ptr;
 +    }
 +
 +  protected:
 +    /**
 +     * Copy constructor, copies are not allowed.
 +     */
 +    Wrap(const Wrap &stat);
 +    /**
 +     * Can't copy stats.
 +     */
 +    void operator=(const Wrap &);
 +
 +  public:
 +    Wrap()
 +    {
 +      map(new Data<Child>(*this));
 +    }
 +
 +    /**
 +     * Set the name and marks this stat to print at the end of simulation.
 +     * @param name The new name.
 +     * @return A reference to this stat.
 +     */
 +    Parent &name(const std::string &_name)
 +    {
 +        Data<Child> *data = this->statData();
 +        data->name = _name;
 +        this->setPrint();
 +        return this->self();
 +    }
 +
 +    /**
 +     * Set the description and marks this stat to print at the end of
 +     * simulation.
 +     * @param desc The new description.
 +     * @return A reference to this stat.
 +     */
 +    Parent &desc(const std::string &_desc)
 +    {
 +        this->statData()->desc = _desc;
 +        return this->self();
 +    }
 +
 +    /**
 +     * Set the precision and marks this stat to print at the end of simulation.
 +     * @param p The new precision
 +     * @return A reference to this stat.
 +     */
 +    Parent &precision(int _precision)
 +    {
 +        this->statData()->precision = _precision;
 +        return this->self();
 +    }
 +
 +    /**
 +     * Set the flags and marks this stat to print at the end of simulation.
 +     * @param f The new flags.
 +     * @return A reference to this stat.
 +     */
 +    Parent &flags(StatFlags _flags)
 +    {
 +        this->statData()->flags |= _flags;
 +        return this->self();
 +    }
 +
 +    /**
 +     * Set the prerequisite stat and marks this stat to print at the end of
 +     * simulation.
 +     * @param prereq The prerequisite stat.
 +     * @return A reference to this stat.
 +     */
 +    template <class Stat>
 +    Parent &prereq(const Stat &prereq)
 +    {
 +        this->statData()->prereq = prereq.statData();
 +        return this->self();
 +    }
 +};
 +
 +template <class Parent, class Child, template <class Child> class Data>
 +class WrapVec : public Wrap<Parent, Child, Data>
 +{
 +  public:
 +    // The following functions are specific to vectors.  If you use them
 +    // in a non vector context, you will get a nice compiler error!
 +
 +    /**
 +     * Set the subfield name for the given index, and marks this stat to print
 +     * at the end of simulation.
 +     * @param index The subfield index.
 +     * @param name The new name of the subfield.
 +     * @return A reference to this stat.
 +     */
 +    Parent &subname(int index, const std::string &name)
 +    {
 +        std::vector<std::string> &subn = this->statData()->subnames;
 +        if (subn.size() <= index)
 +            subn.resize(index + 1);
 +        subn[index] = name;
 +        return this->self();
 +    }
 +
 +    /**
 +     * Set the subfield description for the given index and marks this stat to
 +     * print at the end of simulation.
 +     * @param index The subfield index.
 +     * @param desc The new description of the subfield
 +     * @return A reference to this stat.
 +     */
 +    Parent &subdesc(int index, const std::string &desc)
 +    {
 +        std::vector<std::string> &subd = this->statData()->subdescs;
 +        if (subd.size() <= index)
 +            subd.resize(index + 1);
 +        subd[index] = desc;
 +
 +        return this->self();
 +    }
 +
 +};
 +
 +template <class Parent, class Child, template <class Child> class Data>
 +class WrapVec2d : public WrapVec<Parent, Child, Data>
 +{
 +  public:
 +    /**
 +     * @warning This makes the assumption that if you're gonna subnames a 2d
 +     * vector, you're subnaming across all y
 +     */
 +    Parent &ysubnames(const char **names)
 +    {
 +        Data<Child> *data = this->statData();
 +        data->y_subnames.resize(this->y);
 +        for (int i = 0; i < this->y; ++i)
 +            data->y_subnames[i] = names[i];
 +        return this->self();
 +    }
 +    Parent &ysubname(int index, const std::string subname)
 +    {
 +        Data<Child> *data = this->statData();
 +        assert(index < this->y);
 +        data->y_subnames.resize(this->y);
 +        data->y_subnames[index] = subname.c_str();
 +        return this->self();
 +    }
 +};
 +
 +//////////////////////////////////////////////////////////////////////
 +//
 +// Simple Statistics
 +//
 +//////////////////////////////////////////////////////////////////////
 +
 +/**
 + * Templatized storage and interface for a simple scalar stat.
 + */
 +struct StatStor
 +{
 +  public:
 +    /** The paramaters for this storage type, none for a scalar. */
 +    struct Params { };
 +
 +  private:
 +    /** The statistic value. */
 +    Counter data;
 +
 +  public:
 +    /**
 +     * Builds this storage element and calls the base constructor of the
 +     * datatype.
 +     */
 +    StatStor(const Params &) : data(Counter()) {}
 +
 +    /**
 +     * The the stat to the given value.
 +     * @param val The new value.
 +     * @param p The paramters of this storage type.
 +     */
 +    void set(Counter val, const Params &p) { data = val; }
 +    /**
 +     * Increment the stat by the given value.
 +     * @param val The new value.
 +     * @param p The paramters of this storage type.
 +     */
 +    void inc(Counter val, const Params &p) { data += val; }
 +    /**
 +     * Decrement the stat by the given value.
 +     * @param val The new value.
 +     * @param p The paramters of this storage type.
 +     */
 +    void dec(Counter val, const Params &p) { data -= val; }
 +    /**
 +     * Return the value of this stat as its base type.
 +     * @param p The params of this storage type.
 +     * @return The value of this stat.
 +     */
 +    Counter value(const Params &p) const { return data; }
 +    /**
 +     * Return the value of this stat as a result type.
 +     * @param p The parameters of this storage type.
 +     * @return The value of this stat.
 +     */
 +    Result result(const Params &p) const { return (Result)data; }
 +    /**
 +     * Reset stat value to default
 +     */
 +    void reset() { data = Counter(); }
 +
 +    /**
 +     * @return true if zero value
 +     */
 +    bool zero() const { return data == Counter(); }
 +};
 +
 +/**
 + * Templatized storage and interface to a per-cycle average stat. This keeps
 + * a current count and updates a total (count * cycles) when this count
 + * changes. This allows the quick calculation of a per cycle count of the item
 + * being watched. This is good for keeping track of residencies in structures
 + * among other things.
-     struct Params
-     {
-         /**
-          * The current count.  We stash this here because the current
-          * value is not a binned value.
-          */
-         Counter current;
-     };
 + */
 +struct AvgStor
 +{
 +  public:
 +    /** The paramaters for this storage type */
-     AvgStor(Params &p) : total(0), last(0) { p.current = Counter(); }
++    struct Params { };
 +
 +  private:
++    /** The current count. */
++    Counter current;
 +    /** The total count for all cycles. */
 +    mutable Result total;
 +    /** The cycle that current last changed. */
 +    mutable Tick last;
 +
 +  public:
 +    /**
 +     * Build and initializes this stat storage.
 +     */
-         total += p.current * (curTick - last);
++    AvgStor(Params &p) : current(0), total(0), last(0) { }
 +
 +    /**
 +     * Set the current count to the one provided, update the total and last
 +     * set values.
 +     * @param val The new count.
 +     * @param p The parameters for this storage.
 +     */
 +    void set(Counter val, Params &p) {
-         p.current = val;
++        total += current * (curTick - last);
 +        last = curTick;
-     void inc(Counter val, Params &p) { set(p.current + val, p); }
++        current = val;
 +    }
 +
 +    /**
 +     * Increment the current count by the provided value, calls set.
 +     * @param val The amount to increment.
 +     * @param p The parameters for this storage.
 +     */
-     void dec(Counter val, Params &p) { set(p.current - val, p); }
++    void inc(Counter val, Params &p) { set(current + val, p); }
 +
 +    /**
 +     * Deccrement the current count by the provided value, calls set.
 +     * @param val The amount to decrement.
 +     * @param p The parameters for this storage.
 +     */
-     Counter value(const Params &p) const { return p.current; }
++    void dec(Counter val, Params &p) { set(current - val, p); }
 +
 +    /**
 +     * Return the current count.
 +     * @param p The parameters for this storage.
 +     * @return The current count.
 +     */
-         total += p.current * (curTick - last);
++    Counter value(const Params &p) const { return current; }
 +
 +    /**
 +     * Return the current average.
 +     * @param p The parameters for this storage.
 +     * @return The current average.
 +     */
 +    Result result(const Params &p) const
 +    {
-         return (Result)(total + p.current) / (Result)(curTick + 1);
++        total += current * (curTick - last);
 +        last = curTick;
-  * Storage template. The storage for this stat is held within the Bin class.
-  * This allows for breaking down statistics across multiple bins easily.
++        return (Result)(total + current) / (Result)(curTick + 1);
 +    }
 +
 +    /**
 +     * Reset stat value to default
 +     */
 +    void reset()
 +    {
 +        total = 0;
 +        last = curTick;
 +    }
 +
 +    /**
 +     * @return true if zero value
 +     */
 +    bool zero() const { return total == 0.0; }
 +};
 +
 +/**
 + * Implementation of a scalar stat. The type of stat is determined by the
- template <class Storage, class Bin>
++ * Storage template.
 + */
-     typedef typename Storage::Params params_t;
-     /** Define the bin type. */
-     typedef typename Bin::template Bin<Storage> bin_t;
++template <class Stor>
 +class ScalarBase : public DataAccess
 +{
 +  public:
++    typedef Stor Storage;
++
 +    /** Define the params of the storage class. */
-     /** The bin of this stat. */
-     bin_t bin;
++    typedef typename Storage::Params Params;
 +
 +  protected:
-     params_t params;
++    /** The storage of this stat. */
++    char storage[sizeof(Storage)];
++
 +    /** The parameters for this stat. */
-      * Retrieve the storage from the bin.
-      * @return The storage object for this stat.
++    Params params;
 +
 +  protected:
 +    /**
-     Storage *data() { return bin.data(params); }
++     * Retrieve the storage.
++     * @param index The vector index to access.
++     * @return The storage object at the given index.
 +     */
-      * Retrieve a const pointer to the storage from the bin.
-      * @return A const pointer to the storage object for this stat.
++    Storage *
++    data()
++    {
++        return reinterpret_cast<Storage *>(storage);
++    }
++
 +    /**
-     const Storage *data() const
++     * Retrieve a const pointer to the storage.
++     * for the given index.
++     * @param index The vector index to access.
++     * @return A const pointer to the storage object at the given index.
 +     */
-         bin_t *_bin = const_cast<bin_t *>(&bin);
-         params_t *_params = const_cast<params_t *>(&params);
-         return _bin->data(*_params);
++    const Storage *
++    data() const
 +    {
-     {
-         bin.init(params);
-     }
++        return reinterpret_cast<const Storage *>(storage);
++    }
++
++    void
++    doInit()
++    {
++        new (storage) Storage(params);
++        setInit();
 +    }
 +
 +  public:
 +    /**
 +     * Return the current value of this stat as its base type.
 +     * @return The current value.
 +     */
 +    Counter value() const { return data()->value(params); }
 +
 +  public:
 +    /**
 +     * Create and initialize this stat, register it with the database.
 +     */
 +    ScalarBase()
-     /**
-      * Return true if stat is binned.
-      *@return True is stat is binned.
-      */
-     bool binned() const { return bin_t::binned; }
++    { }
 +
 +  public:
 +    // Common operators for stats
 +    /**
 +     * Increment the stat by 1. This calls the associated storage object inc
 +     * function.
 +     */
 +    void operator++() { data()->inc(1, params); }
 +    /**
 +     * Decrement the stat by 1. This calls the associated storage object dec
 +     * function.
 +     */
 +    void operator--() { data()->dec(1, params); }
 +
 +    /** Increment the stat by 1. */
 +    void operator++(int) { ++*this; }
 +    /** Decrement the stat by 1. */
 +    void operator--(int) { --*this; }
 +
 +    /**
 +     * Set the data value to the given value. This calls the associated storage
 +     * object set function.
 +     * @param v The new value.
 +     */
 +    template <typename U>
 +    void operator=(const U &v) { data()->set(v, params); }
 +
 +    /**
 +     * Increment the stat by the given value. This calls the associated
 +     * storage object inc function.
 +     * @param v The value to add.
 +     */
 +    template <typename U>
 +    void operator+=(const U &v) { data()->inc(v, params); }
 +
 +    /**
 +     * Decrement the stat by the given value. This calls the associated
 +     * storage object dec function.
 +     * @param v The value to substract.
 +     */
 +    template <typename U>
 +    void operator-=(const U &v) { data()->dec(v, params); }
 +
 +    /**
 +     * Return the number of elements, always 1 for a scalar.
 +     * @return 1.
 +     */
 +    size_t size() const { return 1; }
-     bool check() const { return bin.initialized(); }
 +
-     void reset() { bin.reset(); }
++    bool check() const { return true; }
 +
 +    /**
 +     * Reset stat value to default
 +     */
-     virtual bool binned() const { return false; }
++    void reset() { data()->reset(); }
 +
 +    Counter value() { return data()->value(params); }
 +
 +    Result result() { return data()->result(params); }
 +
 +    Result total() { return result(); }
 +
 +    bool zero() { return result() == 0.0; }
 +
 +};
 +
 +class ProxyData : public ScalarData
 +{
 +  public:
 +    virtual void visit(Visit &visitor) { visitor.visit(*this); }
-     bool binned() const { return proxy->binned(); }
 +    virtual std::string str() const { return to_string(value()); }
 +    virtual size_t size() const { return 1; }
 +    virtual bool zero() const { return value() == 0; }
 +    virtual bool check() const { return true; }
 +    virtual void reset() { }
 +};
 +
 +template <class T>
 +class ValueProxy : public ProxyData
 +{
 +  private:
 +    T *scalar;
 +
 +  public:
 +    ValueProxy(T &val) : scalar(&val) {}
 +    virtual Counter value() const { return *scalar; }
 +    virtual Result result() const { return *scalar; }
 +    virtual Result total() const { return *scalar; }
 +};
 +
 +template <class T>
 +class FunctorProxy : public ProxyData
 +{
 +  private:
 +    T *functor;
 +
 +  public:
 +    FunctorProxy(T &func) : functor(&func) {}
 +    virtual Counter value() const { return (*functor)(); }
 +    virtual Result result() const { return (*functor)(); }
 +    virtual Result total() const { return (*functor)(); }
 +};
 +
 +class ValueBase : public DataAccess
 +{
 +  private:
 +    ProxyData *proxy;
 +
 +  public:
 +    ValueBase() : proxy(NULL) { }
 +    ~ValueBase() { if (proxy) delete proxy; }
 +
 +    template <class T>
 +    void scalar(T &value)
 +    {
 +        proxy = new ValueProxy<T>(value);
 +        setInit();
 +    }
 +
 +    template <class T>
 +    void functor(T &func)
 +    {
 +        proxy = new FunctorProxy<T>(func);
 +        setInit();
 +    }
 +
 +    Counter value() { return proxy->value(); }
 +    Result result() const { return proxy->result(); }
 +    Result total() const { return proxy->total(); };
 +    size_t size() const { return proxy->size(); }
 +
- template <class Storage, class Bin>
- class ScalarProxy;
- /**
-  * Implementation of a vector of stats. The type of stat is determined by the
-  * Storage class. @sa ScalarBase
-  */
- template <class Storage, class Bin>
- class VectorBase : public DataAccess
- {
-   public:
-     /** Define the params of the storage class. */
-     typedef typename Storage::Params params_t;
-     /** Define the bin type. */
-     typedef typename Bin::template VectorBin<Storage> bin_t;
-   protected:
-     /** The bin of this stat. */
-     bin_t bin;
-     /** The parameters for this stat. */
-     params_t params;
-   protected:
-     /**
-      * Retrieve the storage from the bin  for the given index.
-      * @param index The vector index to access.
-      * @return The storage object at the given index.
-      */
-     Storage *data(int index) { return bin.data(index, params); }
-     /**
-      * Retrieve a const pointer to the storage from the bin
-      * for the given index.
-      * @param index The vector index to access.
-      * @return A const pointer to the storage object at the given index.
-      */
-     const Storage *data(int index) const
-     {
-         bin_t *_bin = const_cast<bin_t *>(&bin);
-         params_t *_params = const_cast<params_t *>(&params);
-         return _bin->data(index, *_params);
-     }
-   public:
-     void value(VCounter &vec) const
-     {
-         vec.resize(size());
-         for (int i = 0; i < size(); ++i)
-             vec[i] = data(i)->value(params);
-     }
-     /**
-      * Copy the values to a local vector and return a reference to it.
-      * @return A reference to a vector of the stat values.
-      */
-     void result(VResult &vec) const
-     {
-         vec.resize(size());
-         for (int i = 0; i < size(); ++i)
-             vec[i] = data(i)->result(params);
-     }
-     /**
-      * @return True is stat is binned.
-      */
-     bool binned() const { return bin_t::binned; }
-     /**
-      * Return a total of all entries in this vector.
-      * @return The total of all vector entries.
-      */
-     Result total() const {
-         Result total = 0.0;
-         for (int i = 0; i < size(); ++i)
-             total += data(i)->result(params);
-         return total;
-     }
-     /**
-      * @return the number of elements in this vector.
-      */
-     size_t size() const { return bin.size(); }
-     bool zero() const
-     {
-         for (int i = 0; i < size(); ++i)
-             if (data(i)->zero())
-                 return true;
-         return false;
-     }
-     bool check() const { return bin.initialized(); }
-     void reset() { bin.reset(); }
-   public:
-     VectorBase() {}
-     /** Friend this class with the associated scalar proxy. */
-     friend class ScalarProxy<Storage, Bin>;
-     /**
-      * Return a reference (ScalarProxy) to the stat at the given index.
-      * @param index The vector index to access.
-      * @return A reference of the stat.
-      */
-     ScalarProxy<Storage, Bin> operator[](int index);
-     void update(StatData *data) {}
- };
- const StatData * getStatData(const void *stat);
 +    std::string str() const { return proxy->str(); }
 +    bool zero() const { return proxy->zero(); }
 +    bool check() const { return proxy != NULL; }
 +    void reset() { }
 +};
 +
 +//////////////////////////////////////////////////////////////////////
 +//
 +// Vector Statistics
 +//
 +//////////////////////////////////////////////////////////////////////
- template <class Storage, class Bin>
 +
 +/**
 + * A proxy class to access the stat at a given index in a VectorBase stat.
 + * Behaves like a ScalarBase.
 + */
-   public:
-     /** Define the params of the storage class. */
-     typedef typename Storage::Params params_t;
-     /** Define the bin type. */
-     typedef typename Bin::template VectorBin<Storage> bin_t;
++template <class Stat>
 +class ScalarProxy
 +{
-     /** Pointer to the bin in the parent VectorBase. */
-     bin_t *bin;
-     /** Pointer to the params in the parent VectorBase. */
-     params_t *params;
 +  private:
-     /** Keep a pointer to the original stat so was can get data */
-     void *stat;
-   protected:
-     /**
-      * Retrieve the storage from the bin.
-      * @return The storage from the bin for this stat.
-      */
-     Storage *data() { return bin->data(index, *params); }
-     /**
-      * Retrieve a const pointer to the storage from the bin.
-      * @return A const pointer to the storage for this stat.
-      */
-     const Storage *data() const
-     {
-         bin_t *_bin = const_cast<bin_t *>(bin);
-         params_t *_params = const_cast<params_t *>(params);
-         return _bin->data(index, *_params);
-     }
++    /** Pointer to the parent Vector. */
++    Stat *stat;
++
 +    /** The index to access in the parent VectorBase. */
 +    int index;
-     Counter value() const { return data()->value(*params); }
 +
 +  public:
 +    /**
 +     * Return the current value of this stat as its base type.
 +     * @return The current value.
 +     */
-     Result result() const { return data()->result(*params); }
++    Counter value() const { return stat->data(index)->value(stat->params); }
 +
 +    /**
 +     * Return the current value of this statas a result type.
 +     * @return The current value.
 +     */
-      * @param b The bin to use.
++    Result result() const { return stat->data(index)->result(stat->params); }
 +
 +  public:
 +    /**
 +     * Create and initialize this proxy, do not register it with the database.
-     ScalarProxy(bin_t &b, params_t &p, int i, void *s)
-         : bin(&b), params(&p), index(i), stat(s)  {}
 +     * @param p The params to use.
 +     * @param i The index to access.
 +     */
-         : bin(sp.bin), params(sp.params), index(sp.index), stat(sp.stat) {}
++    ScalarProxy(Stat *s, int i)
++        : stat(s), index(i)
++    {
++        assert(stat);
++    }
++
 +    /**
 +     * Create a copy of the provided ScalarProxy.
 +     * @param sp The proxy to copy.
 +     */
 +    ScalarProxy(const ScalarProxy &sp)
-         bin = sp.bin;
-         params = sp.params;
-         index = sp.index;
++        : stat(sp.stat), index(sp.index)
++    {}
++
 +    /**
 +     * Set this proxy equal to the provided one.
 +     * @param sp The proxy to copy.
 +     * @return A reference to this proxy.
 +     */
 +    const ScalarProxy &operator=(const ScalarProxy &sp) {
-     void operator++() { data()->inc(1, *params); }
 +        stat = sp.stat;
++        index = sp.index;
 +        return *this;
 +    }
 +
 +  public:
 +    // Common operators for stats
 +    /**
 +     * Increment the stat by 1. This calls the associated storage object inc
 +     * function.
 +     */
-     void operator--() { data()->dec(1, *params); }
++    void operator++() { stat->data(index)->inc(1, stat->params); }
 +    /**
 +     * Decrement the stat by 1. This calls the associated storage object dec
 +     * function.
 +     */
-     void operator=(const U &v) { data()->set(v, *params); }
++    void operator--() { stat->data(index)->dec(1, stat->params); }
 +
 +    /** Increment the stat by 1. */
 +    void operator++(int) { ++*this; }
 +    /** Decrement the stat by 1. */
 +    void operator--(int) { --*this; }
 +
 +    /**
 +     * Set the data value to the given value. This calls the associated storage
 +     * object set function.
 +     * @param v The new value.
 +     */
 +    template <typename U>
-     void operator+=(const U &v) { data()->inc(v, *params); }
++    void operator=(const U &v) { stat->data(index)->set(v, stat->params); }
 +
 +    /**
 +     * Increment the stat by the given value. This calls the associated
 +     * storage object inc function.
 +     * @param v The value to add.
 +     */
 +    template <typename U>
-     void operator-=(const U &v) { data()->dec(v, *params); }
++    void operator+=(const U &v) { stat->data(index)->inc(v, stat->params); }
 +
 +    /**
 +     * Decrement the stat by the given value. This calls the associated
 +     * storage object dec function.
 +     * @param v The value to substract.
 +     */
 +    template <typename U>
-     /**
-      * Return true if stat is binned.
-      *@return false since Proxies aren't printed/binned
-      */
-     bool binned() const { return false; }
++    void operator-=(const U &v) { stat->data(index)->dec(v, stat->params); }
 +
 +    /**
 +     * Return the number of elements, always 1 for a scalar.
 +     * @return 1.
 +     */
 +    size_t size() const { return 1; }
 +
-     const StatData *statData() const { return getStatData(stat); }
-     std::string str() const
 +    /**
 +     * This stat has no state.  Nothing to reset
 +     */
 +    void reset() {  }
 +
 +  public:
-         return csprintf("%s[%d]", this->statData()->name, index);
++    std::string
++    str() const
 +    {
- template <class Storage, class Bin>
- inline ScalarProxy<Storage, Bin>
- VectorBase<Storage, Bin>::operator[](int index)
++        return csprintf("%s[%d]", stat->str(), index);
 +
 +    }
 +};
 +
-     assert (index >= 0 && index < size());
-     return ScalarProxy<Storage, Bin>(bin, params, index, this);
- }
++/**
++ * Implementation of a vector of stats. The type of stat is determined by the
++ * Storage class. @sa ScalarBase
++ */
++template <class Stor>
++class VectorBase : public DataAccess
 +{
- template <class Storage, class Bin>
- class VectorProxy;
++  public:
++    typedef Stor Storage;
++
++    /** Define the params of the storage class. */
++    typedef typename Storage::Params Params;
 +
- template <class Storage, class Bin>
- class Vector2dBase : public DataAccess
- {
-   public:
-     typedef typename Storage::Params params_t;
-     typedef typename Bin::template VectorBin<Storage> bin_t;
++    /** Proxy type */
++    typedef ScalarProxy<VectorBase<Storage> > Proxy;
 +
-     size_t x;
-     size_t y;
-     bin_t bin;
-     params_t params;
++    friend class ScalarProxy<VectorBase<Storage> >;
 +
 +  protected:
-     Storage *data(int index) { return bin.data(index, params); }
-     const Storage *data(int index) const
++    /** The storage of this stat. */
++    Storage *storage;
++    size_t _size;
++
++    /** The parameters for this stat. */
++    Params params;
 +
 +  protected:
-         bin_t *_bin = const_cast<bin_t *>(&bin);
-         params_t *_params = const_cast<params_t *>(&params);
-         return _bin->data(index, *_params);
++    /**
++     * Retrieve the storage.
++     * @param index The vector index to access.
++     * @return The storage object at the given index.
++     */
++    Storage *data(int index) { return &storage[index]; }
++
++    /**
++     * Retrieve a const pointer to the storage.
++     * @param index The vector index to access.
++     * @return A const pointer to the storage object at the given index.
++     */
++    const Storage *data(int index) const { return &storage[index]; }
++
++    void
++    doInit(int s)
 +    {
-     Vector2dBase() {}
++        assert(s > 0 && "size must be positive!");
++        assert(!storage && "already initialized");
++        _size = s;
++
++        char *ptr = new char[_size * sizeof(Storage)];
++        storage = reinterpret_cast<Storage *>(ptr);
++
++        for (int i = 0; i < _size; ++i)
++            new (&storage[i]) Storage(params);
++
++        setInit();
 +    }
 +
 +  public:
-     void update(Vector2dData *data)
++    void value(VCounter &vec) const
++    {
++        vec.resize(size());
++        for (int i = 0; i < size(); ++i)
++            vec[i] = data(i)->value(params);
++    }
 +
-         int size = this->size();
-         data->cvec.resize(size);
-         for (int i = 0; i < size; ++i)
-             data->cvec[i] = this->data(i)->value(params);
++    /**
++     * Copy the values to a local vector and return a reference to it.
++     * @return A reference to a vector of the stat values.
++     */
++    void result(VResult &vec) const
 +    {
-     std::string ysubname(int i) const { return (*this->y_subnames)[i]; }
++        vec.resize(size());
++        for (int i = 0; i < size(); ++i)
++            vec[i] = data(i)->result(params);
 +    }
 +
-     friend class VectorProxy<Storage, Bin>;
-     VectorProxy<Storage, Bin> operator[](int index);
++    /**
++     * Return a total of all entries in this vector.
++     * @return The total of all vector entries.
++     */
++    Result total() const {
++        Result total = 0.0;
++        for (int i = 0; i < size(); ++i)
++            total += data(i)->result(params);
++        return total;
++    }
++
++    /**
++     * @return the number of elements in this vector.
++     */
++    size_t size() const { return _size; }
 +
-     size_t size() const { return bin.size(); }
-     bool zero() const { return data(0)->value(params) == 0.0; }
++    bool
++    zero() const
++    {
++        for (int i = 0; i < size(); ++i)
++            if (data(i)->zero())
++                return false;
++        return true;
++    }
 +
-      * Reset stat value to default
++    bool
++    check() const
++    {
++        return storage != NULL;
++    }
++
++    void
++    reset()
++    {
++        for (int i = 0; i < size(); ++i)
++            data(i)->reset();
++    }
++
++  public:
++    VectorBase()
++        : storage(NULL)
++    {}
++
++    ~VectorBase()
++    {
++        if (!storage)
++            return;
++
++        for (int i = 0; i < _size; ++i)
++            data(i)->~Storage();
++        delete [] reinterpret_cast<char *>(storage);
++    }
 +
 +    /**
-     void reset() { bin.reset(); }
++     * Return a reference (ScalarProxy) to the stat at the given index.
++     * @param index The vector index to access.
++     * @return A reference of the stat.
 +     */
-     bool check() { return bin.initialized(); }
++    Proxy
++    operator[](int index)
++    {
++        assert (index >= 0 && index < size());
++        return Proxy(this, index);
++    }
 +
- template <class Storage, class Bin>
++    void update(StatData *data) {}
 +};
 +
-   public:
-     typedef typename Storage::Params params_t;
-     typedef typename Bin::template VectorBin<Storage> bin_t;
++template <class Stat>
 +class VectorProxy
 +{
-     bin_t *bin;
-     params_t *params;
 +  private:
-     void *stat;
++    Stat *stat;
 +    int offset;
 +    int len;
-     mutable VResult *vec;
 +
 +  private:
-     Storage *data(int index) {
++    mutable VResult vec;
 +
-         return bin->data(offset + index, *params);
++    typename Stat::Storage *
++    data(int index)
++    {
 +        assert(index < len);
-     const Storage *data(int index) const {
-         bin_t *_bin = const_cast<bin_t *>(bin);
-         params_t *_params = const_cast<params_t *>(params);
-         return _bin->data(offset + index, *_params);
++        return stat->data(offset + index);
 +    }
 +
-     const VResult &result() const {
-         if (vec)
-             vec->resize(size());
-         else
-             vec = new VResult(size());
++    const typename Stat::Storage *
++    data(int index) const
++    {
++        assert(index < len);
++        return const_cast<Stat *>(stat)->data(offset + index);
 +    }
 +
 +  public:
-             (*vec)[i] = data(i)->result(*params);
++    const VResult &
++    result() const
++    {
++        vec.resize(size());
 +
 +        for (int i = 0; i < size(); ++i)
-         return *vec;
++            vec[i] = data(i)->result(stat->params);
 +
-     Result total() const {
-         Result total = 0.0;
++        return vec;
 +    }
 +
-             total += data(i)->result(*params);
++    Result
++    total() const
++    {
++        Result total = 0;
 +        for (int i = 0; i < size(); ++i)
-     VectorProxy(bin_t &b, params_t &p, int o, int l, void *s)
-         : bin(&b), params(&p), offset(o), len(l), stat(s), vec(NULL)
++            total += data(i)->result(stat->params);
 +        return total;
 +    }
 +
 +  public:
-         : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len),
-           stat(sp.stat), vec(NULL)
-     {
-     }
-     ~VectorProxy()
++    VectorProxy(Stat *s, int o, int l)
++        : stat(s), offset(o), len(l)
 +    {
 +    }
 +
 +    VectorProxy(const VectorProxy &sp)
-         if (vec)
-             delete vec;
++        : stat(sp.stat), offset(sp.offset), len(sp.len)
 +    {
-     const VectorProxy &operator=(const VectorProxy &sp)
 +    }
 +
-         bin = sp.bin;
-         params = sp.params;
++    const VectorProxy &
++    operator=(const VectorProxy &sp)
 +    {
-         stat = sp.stat;
-         if (vec)
-             delete vec;
-         vec = NULL;
++        stat = sp.stat;
 +        offset = sp.offset;
 +        len = sp.len;
-     ScalarProxy<Storage, Bin> operator[](int index)
 +        return *this;
 +    }
 +
-         return ScalarProxy<Storage, Bin>(*bin, *params, offset + index, stat);
++    ScalarProxy<Stat> operator[](int index)
 +    {
 +        assert (index >= 0 && index < size());
-     /**
-      * Return true if stat is binned.
-      *@return false since Proxies aren't printed/binned
-      */
-     bool binned() const { return false; }
++        return ScalarProxy<Stat>(stat, offset + index);
 +    }
 +
 +    size_t size() const { return len; }
 +
- template <class Storage, class Bin>
- inline VectorProxy<Storage, Bin>
- Vector2dBase<Storage, Bin>::operator[](int index)
 +    /**
 +     * This stat has no state.  Nothing to reset.
 +     */
 +    void reset() { }
 +};
 +
-     int offset = index * y;
-     assert (index >= 0 && offset < size());
-     return VectorProxy<Storage, Bin>(bin, params, offset, y, this);
- }
++template <class Stor>
++class Vector2dBase : public DataAccess
 +{
-     /**
-      * Construct this storage with the supplied params.
-      * @param params The parameters.
-      */
++  public:
++    typedef Stor Storage;
++    typedef typename Storage::Params Params;
++    typedef VectorProxy<Vector2dBase<Storage> > Proxy;
++    friend class ScalarProxy<Vector2dBase<Storage> >;
++    friend class VectorProxy<Vector2dBase<Storage> >;
++
++  protected:
++    size_t x;
++    size_t y;
++    size_t _size;
++    Storage *storage;
++    Params params;
++
++  protected:
++    Storage *data(int index) { return &storage[index]; }
++    const Storage *data(int index) const { return &storage[index]; }
++
++    void
++    doInit(int _x, int _y)
++    {
++        assert(_x > 0 && _y > 0 && "sizes must be positive!");
++        assert(!storage && "already initialized");
++
++        Vector2dData *statdata = dynamic_cast<Vector2dData *>(find());
++
++        x = _x;
++        y = _y;
++        statdata->x = _x;
++        statdata->y = _y;
++        _size = x * y;
++
++        char *ptr = new char[_size * sizeof(Storage)];
++        storage = reinterpret_cast<Storage *>(ptr);
++
++        for (int i = 0; i < _size; ++i)
++            new (&storage[i]) Storage(params);
++
++        setInit();
++    }
++
++  public:
++    Vector2dBase()
++        : storage(NULL)
++    {}
++
++    ~Vector2dBase()
++    {
++        if (!storage)
++            return;
++
++        for (int i = 0; i < _size; ++i)
++            data(i)->~Storage();
++        delete [] reinterpret_cast<char *>(storage);
++    }
++
++    void
++    update(Vector2dData *newdata)
++    {
++        int size = this->size();
++        newdata->cvec.resize(size);
++        for (int i = 0; i < size; ++i)
++            newdata->cvec[i] = data(i)->value(params);
++    }
++
++    std::string ysubname(int i) const { return (*this->y_subnames)[i]; }
++
++    Proxy
++    operator[](int index)
++    {
++        int offset = index * y;
++        assert (index >= 0 && offset + index < size());
++        return Proxy(this, offset, y);
++    }
++
++
++    size_t
++    size() const
++    {
++        return _size;
++    }
++
++    bool
++    zero() const
++    {
++        return data(0)->zero();
++#if 0
++        for (int i = 0; i < size(); ++i)
++            if (!data(i)->zero())
++                return false;
++        return true;
++#endif
++    }
++
++    /**
++     * Reset stat value to default
++     */
++    void
++    reset()
++    {
++        for (int i = 0; i < size(); ++i)
++            data(i)->reset();
++    }
++
++    bool
++    check()
++    {
++        return storage != NULL;
++    }
++};
 +
 +//////////////////////////////////////////////////////////////////////
 +//
 +// Non formula statistics
 +//
 +//////////////////////////////////////////////////////////////////////
 +
 +/**
 + * Templatized storage and interface for a distrbution stat.
 + */
 +struct DistStor
 +{
 +  public:
 +    /** The parameters for a distribution stat. */
 +    struct Params
 +    {
 +        /** The minimum value to track. */
 +        Counter min;
 +        /** The maximum value to track. */
 +        Counter max;
 +        /** The number of entries in each bucket. */
 +        Counter bucket_size;
 +        /** The number of buckets. Equal to (max-min)/bucket_size. */
 +        int size;
 +    };
 +    enum { fancy = false };
 +
 +  private:
 +    /** The smallest value sampled. */
 +    Counter min_val;
 +    /** The largest value sampled. */
 +    Counter max_val;
 +    /** The number of values sampled less than min. */
 +    Counter underflow;
 +    /** The number of values sampled more than max. */
 +    Counter overflow;
 +    /** The current sum. */
 +    Counter sum;
 +    /** The sum of squares. */
 +    Counter squares;
 +    /** The number of samples. */
 +    Counter samples;
 +    /** Counter for each bucket. */
 +    VCounter cvec;
 +
 +  public:
-         : min_val(INT_MAX), max_val(INT_MIN), underflow(Counter()),
-           overflow(Counter()), sum(Counter()), squares(Counter()),
-           samples(Counter()), cvec(params.size)
 +    DistStor(const Params &params)
- template <class Storage, class Bin>
++        : cvec(params.size)
 +    {
 +        reset();
 +    }
 +
 +    /**
 +     * Add a value to the distribution for the given number of times.
 +     * @param val The value to add.
 +     * @param number The number of times to add the value.
 +     * @param params The paramters of the distribution.
 +     */
 +    void sample(Counter val, int number, const Params &params)
 +    {
 +        if (val < params.min)
 +            underflow += number;
 +        else if (val > params.max)
 +            overflow += number;
 +        else {
 +            int index = (int)floor((val - params.min) / params.bucket_size);
 +            assert(index < size(params));
 +            cvec[index] += number;
 +        }
 +
 +        if (val < min_val)
 +            min_val = val;
 +
 +        if (val > max_val)
 +            max_val = val;
 +
 +        Counter sample = val * number;
 +        sum += sample;
 +        squares += sample * sample;
 +        samples += number;
 +    }
 +
 +    /**
 +     * Return the number of buckets in this distribution.
 +     * @return the number of buckets.
 +     * @todo Is it faster to return the size from the parameters?
 +     */
 +    size_t size(const Params &) const { return cvec.size(); }
 +
 +    /**
 +     * Returns true if any calls to sample have been made.
 +     * @param params The paramters of the distribution.
 +     * @return True if any values have been sampled.
 +     */
 +    bool zero(const Params &params) const
 +    {
 +        return samples == Counter();
 +    }
 +
 +    void update(DistDataData *data, const Params &params)
 +    {
 +        data->min = params.min;
 +        data->max = params.max;
 +        data->bucket_size = params.bucket_size;
 +        data->size = params.size;
 +
 +        data->min_val = (min_val == INT_MAX) ? 0 : min_val;
 +        data->max_val = (max_val == INT_MIN) ? 0 : max_val;
 +        data->underflow = underflow;
 +        data->overflow = overflow;
 +        data->cvec.resize(params.size);
 +        for (int i = 0; i < params.size; ++i)
 +            data->cvec[i] = cvec[i];
 +
 +        data->sum = sum;
 +        data->squares = squares;
 +        data->samples = samples;
 +    }
 +
 +    /**
 +     * Reset stat value to default
 +     */
 +    void reset()
 +    {
 +        min_val = INT_MAX;
 +        max_val = INT_MIN;
 +        underflow = 0;
 +        overflow = 0;
 +
 +        int size = cvec.size();
 +        for (int i = 0; i < size; ++i)
 +            cvec[i] = Counter();
 +
 +        sum = Counter();
 +        squares = Counter();
 +        samples = Counter();
 +    }
 +};
 +
 +/**
 + * Templatized storage and interface for a distribution that calculates mean
 + * and variance.
 + */
 +struct FancyStor
 +{
 +  public:
 +    /**
 +     * No paramters for this storage.
 +     */
 +    struct Params {};
 +    enum { fancy = true };
 +
 +  private:
 +    /** The current sum. */
 +    Counter sum;
 +    /** The sum of squares. */
 +    Counter squares;
 +    /** The number of samples. */
 +    Counter samples;
 +
 +  public:
 +    /**
 +     * Create and initialize this storage.
 +     */
 +    FancyStor(const Params &)
 +        : sum(Counter()), squares(Counter()), samples(Counter())
 +    { }
 +
 +    /**
 +     * Add a value the given number of times to this running average.
 +     * Update the running sum and sum of squares, increment the number of
 +     * values seen by the given number.
 +     * @param val The value to add.
 +     * @param number The number of times to add the value.
 +     * @param p The parameters of this stat.
 +     */
 +    void sample(Counter val, int number, const Params &p)
 +    {
 +        Counter value = val * number;
 +        sum += value;
 +        squares += value * value;
 +        samples += number;
 +    }
 +
 +    void update(DistDataData *data, const Params &params)
 +    {
 +        data->sum = sum;
 +        data->squares = squares;
 +        data->samples = samples;
 +    }
 +
 +    /**
 +     * Return the number of entries in this stat, 1
 +     * @return 1.
 +     */
 +    size_t size(const Params &) const { return 1; }
 +
 +    /**
 +     * Return true if no samples have been added.
 +     * @return True if no samples have been added.
 +     */
 +    bool zero(const Params &) const { return samples == Counter(); }
 +
 +    /**
 +     * Reset stat value to default
 +     */
 +    void reset()
 +    {
 +        sum = Counter();
 +        squares = Counter();
 +        samples = Counter();
 +    }
 +};
 +
 +/**
 + * Templatized storage for distribution that calculates per cycle mean and
 + * variance.
 + */
 +struct AvgFancy
 +{
 +  public:
 +    /** No parameters for this storage. */
 +    struct Params {};
 +    enum { fancy = true };
 +
 +  private:
 +    /** Current total. */
 +    Counter sum;
 +    /** Current sum of squares. */
 +    Counter squares;
 +
 +  public:
 +    /**
 +     * Create and initialize this storage.
 +     */
 +    AvgFancy(const Params &) : sum(Counter()), squares(Counter()) {}
 +
 +    /**
 +     * Add a value to the distribution for the given number of times.
 +     * Update the running sum and sum of squares.
 +     * @param val The value to add.
 +     * @param number The number of times to add the value.
 +     * @param p The paramters of the distribution.
 +     */
 +    void sample(Counter val, int number, const Params &p)
 +    {
 +        Counter value = val * number;
 +        sum += value;
 +        squares += value * value;
 +    }
 +
 +    void update(DistDataData *data, const Params &params)
 +    {
 +        data->sum = sum;
 +        data->squares = squares;
 +        data->samples = curTick;
 +    }
 +
 +    /**
 +     * Return the number of entries, in this case 1.
 +     * @return 1.
 +     */
 +    size_t size(const Params &params) const { return 1; }
 +    /**
 +     * Return true if no samples have been added.
 +     * @return True if the sum is zero.
 +     */
 +    bool zero(const Params &params) const { return sum == Counter(); }
 +    /**
 +     * Reset stat value to default
 +     */
 +    void reset()
 +    {
 +        sum = Counter();
 +        squares = Counter();
 +    }
 +};
 +
 +/**
 + * Implementation of a distribution stat. The type of distribution is
 + * determined by the Storage template. @sa ScalarBase
 + */
-     typedef typename Storage::Params params_t;
-     /** Define the bin type. */
-     typedef typename Bin::template Bin<Storage> bin_t;
++template <class Stor>
 +class DistBase : public DataAccess
 +{
 +  public:
++    typedef Stor Storage;
 +    /** Define the params of the storage class. */
-     /** The bin of this stat. */
-     bin_t bin;
++    typedef typename Storage::Params Params;
 +
 +  protected:
-     params_t params;
++    /** The storage for this stat. */
++    char storage[sizeof(Storage)];
++
 +    /** The parameters for this stat. */
-      * Retrieve the storage from the bin.
++    Params params;
 +
 +  protected:
 +    /**
-     Storage *data() { return bin.data(params); }
++     * Retrieve the storage.
 +     * @return The storage object for this stat.
 +     */
-      * Retrieve a const pointer to the storage from the bin.
++    Storage *data()
++    {
++        return reinterpret_cast<Storage *>(storage);
++    }
++
 +    /**
-     const Storage *data() const
++     * Retrieve a const pointer to the storage.
 +     * @return A const pointer to the storage object for this stat.
 +     */
-         bin_t *_bin = const_cast<bin_t *>(&bin);
-         params_t *_params = const_cast<params_t *>(&params);
-         return _bin->data(*_params);
++    const Storage *
++    data() const
 +    {
-     /**
-      * @return True is stat is binned.
-      */
-     bool binned() const { return bin_t::binned; }
++        return reinterpret_cast<const Storage *>(storage);
++    }
++
++    void
++    doInit()
++    {
++        new (storage) Storage(params);
++        setInit();
 +    }
 +
 +  public:
 +    DistBase() { }
 +
 +    /**
 +     * Add a value to the distribtion n times. Calls sample on the storage
 +     * class.
 +     * @param v The value to add.
 +     * @param n The number of times to add it, defaults to 1.
 +     */
 +    template <typename U>
 +    void sample(const U &v, int n = 1) { data()->sample(v, n, params); }
 +
 +    /**
 +     * Return the number of entries in this stat.
 +     * @return The number of entries.
 +     */
 +    size_t size() const { return data()->size(params); }
 +    /**
 +     * Return true if no samples have been added.
 +     * @return True if there haven't been any samples.
 +     */
 +    bool zero() const { return data()->zero(params); }
 +
 +    void update(DistData *base)
 +    {
 +        base->data.fancy = Storage::fancy;
 +        data()->update(&(base->data), params);
 +    }
-     void reset()
++
 +    /**
 +     * Reset stat value to default
 +     */
-         bin.reset();
++    void
++    reset()
 +    {
-     bool check() { return bin.initialized(); }
++        data()->reset();
 +    }
 +
- template <class Storage, class Bin>
++    bool
++    check()
++    {
++        return true;
++    }
 +};
 +
- template <class Storage, class Bin>
++template <class Stat>
 +class DistProxy;
 +
-     typedef typename Storage::Params params_t;
-     typedef typename Bin::template VectorBin<Storage> bin_t;
++template <class Stor>
 +class VectorDistBase : public DataAccess
 +{
 +  public:
-     bin_t bin;
-     params_t params;
++    typedef Stor Storage;
++    typedef typename Storage::Params Params;
++    typedef DistProxy<VectorDistBase<Storage> > Proxy;
++    friend class DistProxy<VectorDistBase<Storage> >;
 +
 +  protected:
-     Storage *data(int index) { return bin.data(index, params); }
-     const Storage *data(int index) const
++    Storage *storage;
++    size_t _size;
++    Params params;
 +
 +  protected:
-         bin_t *_bin = const_cast<bin_t *>(&bin);
-         params_t *_params = const_cast<params_t *>(&params);
-         return _bin->data(index, *_params);
++    Storage *
++    data(int index)
++    {
++        return &storage[index];
++    }
++
++    const Storage *
++    data(int index) const
 +    {
-     VectorDistBase() {}
++        return &storage[index];
++    }
++
++    void
++    doInit(int s)
++    {
++        assert(s > 0 && "size must be positive!");
++        assert(!storage && "already initialized");
++        _size = s;
++
++        char *ptr = new char[_size * sizeof(Storage)];
++        storage = reinterpret_cast<Storage *>(ptr);
++
++        for (int i = 0; i < _size; ++i)
++            new (&storage[i]) Storage(params);
++
++        setInit();
 +    }
 +
 +  public:
-     friend class DistProxy<Storage, Bin>;
-     DistProxy<Storage, Bin> operator[](int index);
-     const DistProxy<Storage, Bin> operator[](int index) const;
++    VectorDistBase()
++        : storage(NULL)
++    {}
 +
-     size_t size() const { return bin.size(); }
-     bool zero() const { return false; }
-     /**
-      * Return true if stat is binned.
-      *@return True is stat is binned.
-      */
-     bool binned() const { return bin_t::binned; }
++    ~VectorDistBase()
++    {
++        if (!storage)
++            return ;
++
++        for (int i = 0; i < _size; ++i)
++            data(i)->~Storage();
++        delete [] reinterpret_cast<char *>(storage);
++    }
++
++    Proxy operator[](int index);
++
++    size_t
++    size() const
++    {
++        return _size;
++    }
++
++    bool
++    zero() const
++    {
++        return false;
++#if 0
++        for (int i = 0; i < size(); ++i)
++            if (!data(i)->zero(params))
++                return false;
++        return true;
++#endif
++    }
 +
-     void reset() { bin.reset(); }
 +    /**
 +     * Reset stat value to default
 +     */
-     bool check() { return bin.initialized(); }
-     void update(VectorDistData *base)
++    void
++    reset()
++    {
++        for (int i = 0; i < size(); ++i)
++            data(i)->reset();
++    }
++
++    bool
++    check()
++    {
++        return storage != NULL;
++    }
 +
- template <class Storage, class Bin>
++    void
++    update(VectorDistData *base)
 +    {
 +        int size = this->size();
 +        base->data.resize(size);
 +        for (int i = 0; i < size; ++i) {
 +            base->data[i].fancy = Storage::fancy;
 +            data(i)->update(&(base->data[i]), params);
 +        }
 +    }
 +};
 +
-   public:
-     typedef typename Storage::Params params_t;
-     typedef typename Bin::template Bin<Storage> bin_t;
-     typedef VectorDistBase<Storage, Bin> base_t;
++template <class Stat>
 +class DistProxy
 +{
-     union {
-         base_t *stat;
-         const base_t *cstat;
-     };
 +  private:
-     Storage *data() { return stat->data(index); }
-     const Storage *data() const { return cstat->data(index); }
++    Stat *stat;
 +    int index;
 +
 +  protected:
-     DistProxy(const VectorDistBase<Storage, Bin> &s, int i)
-         : cstat(&s), index(i) {}
++    typename Stat::Storage *data() { return stat->data(index); }
++    const typename Stat::Storage *data() const { return stat->data(index); }
 +
 +  public:
-         : cstat(sp.cstat), index(sp.index) {}
-     const DistProxy &operator=(const DistProxy &sp) {
-         cstat = sp.cstat; index = sp.index; return *this;
++    DistProxy(Stat *s, int i)
++        : stat(s), index(i)
++    {}
++
 +    DistProxy(const DistProxy &sp)
-     void sample(const U &v, int n = 1) { data()->sample(v, n, cstat->params); }
++        : stat(sp.stat), index(sp.index)
++    {}
++
++    const DistProxy &operator=(const DistProxy &sp)
++    {
++        stat = sp.stat;
++        index = sp.index;
++        return *this;
 +    }
 +
 +  public:
 +    template <typename U>
-     size_t size() const { return 1; }
-     bool zero() const { return data()->zero(cstat->params); }
-     /**
-      * Return true if stat is binned.
-      *@return false since Proxies are not binned/printed.
-      */
-     bool binned() const { return false; }
++    void
++    sample(const U &v, int n = 1)
++    {
++        data()->sample(v, n, stat->params);
++    }
++
++    size_t
++    size() const
++    {
++        return 1;
++    }
++
++    bool
++    zero() const
++    {
++        return data()->zero(stat->params);
++    }
 +
- template <class Storage, class Bin>
- inline DistProxy<Storage, Bin>
- VectorDistBase<Storage, Bin>::operator[](int index)
 +    /**
 +     * Proxy has no state.  Nothing to reset.
 +     */
 +    void reset() { }
 +};
 +
-     return DistProxy<Storage, Bin>(*this, index);
- }
- template <class Storage, class Bin>
- inline const DistProxy<Storage, Bin>
- VectorDistBase<Storage, Bin>::operator[](int index) const
- {
-     assert (index >= 0 && index < size());
-     return DistProxy<Storage, Bin>(*this, index);
++template <class Storage>
++inline typename VectorDistBase<Storage>::Proxy
++VectorDistBase<Storage>::operator[](int index)
 +{
 +    assert (index >= 0 && index < size());
- template <class Storage, class Bin>
++    return typename VectorDistBase<Storage>::Proxy(this, index);
 +}
 +
 +#if 0
- VectorDistBase<Storage, Bin>::total(int index) const
++template <class Storage>
 +Result
-     for (int i=0; i < x_size(); ++i) {
-         total += data(i)->result(*params);
++VectorDistBase<Storage>::total(int index) const
 +{
 +    int total = 0;
-     /**
-      * Return true if stat is binned.
-      *@return True is stat is binned.
-      */
-     virtual bool binned() const = 0;
++    for (int i = 0; i < x_size(); ++i) {
++        total += data(i)->result(stat->params);
 +    }
 +}
 +#endif
 +
 +//////////////////////////////////////////////////////////////////////
 +//
 +//  Formula Details
 +//
 +//////////////////////////////////////////////////////////////////////
 +
 +/**
 + * Base class for formula statistic node. These nodes are used to build a tree
 + * that represents the formula.
 + */
 +class Node : public RefCounted
 +{
 +  public:
 +    /**
 +     * Return the number of nodes in the subtree starting at this node.
 +     * @return the number of nodes in this subtree.
 +     */
 +    virtual size_t size() const = 0;
 +    /**
 +     * Return the result vector of this subtree.
 +     * @return The result vector of this subtree.
 +     */
 +    virtual const VResult &result() const = 0;
 +    /**
 +     * Return the total of the result vector.
 +     * @return The total of the result vector.
 +     */
 +    virtual Result total() const = 0;
-     /**
-      * Return true if stat is binned.
-      *@return True is stat is binned.
-      */
-     virtual bool binned() const { return data->binned(); }
 +
 +    /**
 +     *
 +     */
 +    virtual std::string str() const = 0;
 +};
 +
 +/** Reference counting pointer to a function Node. */
 +typedef RefCountingPtr<Node> NodePtr;
 +
 +class ScalarStatNode : public Node
 +{
 +  private:
 +    const ScalarData *data;
 +    mutable VResult vresult;
 +
 +  public:
 +    ScalarStatNode(const ScalarData *d) : data(d), vresult(1) {}
 +    virtual const VResult &result() const
 +    {
 +        vresult[0] = data->result();
 +        return vresult;
 +    }
 +    virtual Result total() const { return data->result(); };
 +
 +    virtual size_t size() const { return 1; }
- template <class Storage, class Bin>
 +
 +    /**
 +     *
 +     */
 +    virtual std::string str() const { return data->name; }
 +};
 +
-     const ScalarProxy<Storage, Bin> proxy;
++template <class Stat>
 +class ScalarProxyNode : public Node
 +{
 +  private:
-     ScalarProxyNode(const ScalarProxy<Storage, Bin> &p)
-         : proxy(p), vresult(1) { }
-     virtual const VResult &result() const
++    const ScalarProxy<Stat> proxy;
 +    mutable VResult vresult;
 +
 +  public:
-     virtual Result total() const { return proxy.result(); };
++    ScalarProxyNode(const ScalarProxy<Stat> &p)
++        : proxy(p), vresult(1)
++    { }
++
++    virtual const VResult &
++    result() const
 +    {
 +        vresult[0] = proxy.result();
 +        return vresult;
 +    }
-     virtual size_t size() const { return 1; }
-     /**
-      * Return true if stat is binned.
-      *@return True is stat is binned.
-      */
-     virtual bool binned() const { return proxy.binned(); }
 +
-     virtual std::string str() const { return proxy.str(); }
++    virtual Result
++    total() const
++    {
++        return proxy.result();
++    }
++
++    virtual size_t
++    size() const
++    {
++        return 1;
++    }
 +
 +    /**
 +     *
 +     */
-     /**
-      * Return true if stat is binned.
-      *@return True is stat is binned.
-      */
-     virtual bool binned() const { return data->binned(); }
++    virtual std::string
++    str() const
++    {
++        return proxy.str();
++    }
 +};
 +
 +class VectorStatNode : public Node
 +{
 +  private:
 +    const VectorData *data;
 +
 +  public:
 +    VectorStatNode(const VectorData *d) : data(d) { }
 +    virtual const VResult &result() const { return data->result(); }
 +    virtual Result total() const { return data->total(); };
 +
 +    virtual size_t size() const { return data->size(); }
-     /**
-      * Return true if stat is binned.
-      *@return False since constants aren't binned.
-      */
-     virtual bool binned() const { return false; }
 +
 +    virtual std::string str() const { return data->name; }
 +};
 +
 +template <class T>
 +class ConstNode : public Node
 +{
 +  private:
 +    VResult vresult;
 +
 +  public:
 +    ConstNode(T s) : vresult(1, (Result)s) {}
 +    const VResult &result() const { return vresult; }
 +    virtual Result total() const { return vresult[0]; };
 +    virtual size_t size() const { return 1; }
-     /**
-      * Return true if child of node is binned.
-      *@return True if child of node is binned.
-      */
-     virtual bool binned() const { return l->binned(); }
 +    virtual std::string str() const { return to_string(vresult[0]); }
 +};
 +
 +template <class Op>
 +struct OpString;
 +
 +template<>
 +struct OpString<std::plus<Result> >
 +{
 +    static std::string str() { return "+"; }
 +};
 +
 +template<>
 +struct OpString<std::minus<Result> >
 +{
 +    static std::string str() { return "-"; }
 +};
 +
 +template<>
 +struct OpString<std::multiplies<Result> >
 +{
 +    static std::string str() { return "*"; }
 +};
 +
 +template<>
 +struct OpString<std::divides<Result> >
 +{
 +    static std::string str() { return "/"; }
 +};
 +
 +template<>
 +struct OpString<std::modulus<Result> >
 +{
 +    static std::string str() { return "%"; }
 +};
 +
 +template<>
 +struct OpString<std::negate<Result> >
 +{
 +    static std::string str() { return "-"; }
 +};
 +
 +template <class Op>
 +class UnaryNode : public Node
 +{
 +  public:
 +    NodePtr l;
 +    mutable VResult vresult;
 +
 +  public:
 +    UnaryNode(NodePtr &p) : l(p) {}
 +
 +    const VResult &result() const
 +    {
 +        const VResult &lvec = l->result();
 +        int size = lvec.size();
 +
 +        assert(size > 0);
 +
 +        vresult.resize(size);
 +        Op op;
 +        for (int i = 0; i < size; ++i)
 +            vresult[i] = op(lvec[i]);
 +
 +        return vresult;
 +    }
 +
 +    Result total() const {
 +        Op op;
 +        return op(l->total());
 +    }
 +
 +    virtual size_t size() const { return l->size(); }
-     /**
-      * Return true if any children of node are binned
-      *@return True if either child of node is binned.
-      */
-     virtual bool binned() const { return (l->binned() || r->binned()); }
 +
 +    virtual std::string str() const
 +    {
 +        return OpString<Op>::str() + l->str();
 +    }
 +};
 +
 +template <class Op>
 +class BinaryNode : public Node
 +{
 +  public:
 +    NodePtr l;
 +    NodePtr r;
 +    mutable VResult vresult;
 +
 +  public:
 +    BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {}
 +
 +    const VResult &result() const
 +    {
 +        Op op;
 +        const VResult &lvec = l->result();
 +        const VResult &rvec = r->result();
 +
 +        assert(lvec.size() > 0 && rvec.size() > 0);
 +
 +        if (lvec.size() == 1 && rvec.size() == 1) {
 +            vresult.resize(1);
 +            vresult[0] = op(lvec[0], rvec[0]);
 +        } else if (lvec.size() == 1) {
 +            int size = rvec.size();
 +            vresult.resize(size);
 +            for (int i = 0; i < size; ++i)
 +                vresult[i] = op(lvec[0], rvec[i]);
 +        } else if (rvec.size() == 1) {
 +            int size = lvec.size();
 +            vresult.resize(size);
 +            for (int i = 0; i < size; ++i)
 +                vresult[i] = op(lvec[i], rvec[0]);
 +        } else if (rvec.size() == lvec.size()) {
 +            int size = rvec.size();
 +            vresult.resize(size);
 +            for (int i = 0; i < size; ++i)
 +                vresult[i] = op(lvec[i], rvec[i]);
 +        }
 +
 +        return vresult;
 +    }
 +
 +    Result total() const {
 +        Op op;
 +        return op(l->total(), r->total());
 +    }
 +
 +    virtual size_t size() const {
 +        int ls = l->size();
 +        int rs = r->size();
 +        if (ls == 1)
 +            return rs;
 +        else if (rs == 1)
 +            return ls;
 +        else {
 +            assert(ls == rs && "Node vector sizes are not equal");
 +            return ls;
 +        }
 +    }
-     /**
-      * Return true if child of node is binned.
-      *@return True if child of node is binned.
-      */
-     virtual bool binned() const { return l->binned(); }
 +
 +    virtual std::string str() const
 +    {
 +        return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
 +    }
 +};
 +
 +template <class Op>
 +class SumNode : public Node
 +{
 +  public:
 +    NodePtr l;
 +    mutable VResult vresult;
 +
 +  public:
 +    SumNode(NodePtr &p) : l(p), vresult(1) {}
 +
 +    const VResult &result() const
 +    {
 +        const VResult &lvec = l->result();
 +        int size = lvec.size();
 +        assert(size > 0);
 +
 +        vresult[0] = 0.0;
 +
 +        Op op;
 +        for (int i = 0; i < size; ++i)
 +            vresult[0] = op(vresult[0], lvec[i]);
 +
 +        return vresult;
 +    }
 +
 +    Result total() const
 +    {
 +        const VResult &lvec = l->result();
 +        int size = lvec.size();
 +        assert(size > 0);
 +
 +        Result vresult = 0.0;
 +
 +        Op op;
 +        for (int i = 0; i < size; ++i)
 +            vresult = op(vresult, lvec[i]);
 +
 +        return vresult;
 +    }
 +
 +    virtual size_t size() const { return 1; }
-  * These are the statistics that are used in the simulator. By default these
-  * store counters and don't use binning, but are templatized to accept any type
-  * and any Bin class.
 +
 +    virtual std::string str() const
 +    {
 +        return csprintf("total(%s)", l->str());
 +    }
 +};
 +
 +
 +//////////////////////////////////////////////////////////////////////
 +//
 +// Visible Statistics Types
 +//
 +//////////////////////////////////////////////////////////////////////
 +/**
 + * @defgroup VisibleStats "Statistic Types"
- /**
-  * This is an easy way to assign all your stats to be binned or not
-  * binned.  If the typedef is NoBin, nothing is binned.  If it is
-  * MainBin, then all stats are binned under that Bin.
-  */
- #if STATS_BINNING
- typedef MainBin DefaultBin;
- #else
- typedef NoBin DefaultBin;
- #endif
++ * These are the statistics that are used in the simulator.
 + * @{
 + */
 +
- template <class Bin = DefaultBin>
- class Scalar
-     : public Wrap<Scalar<Bin>,
-                   ScalarBase<StatStor, Bin>,
-                   ScalarStatData>
 +/**
 + * This is a simple scalar statistic, like a counter.
 + * @sa Stat, ScalarBase, StatStor
 + */
-     typedef ScalarBase<StatStor, Bin> Base;
++template<int N = 0>
++class Scalar : public Wrap<Scalar<N>, ScalarBase<StatStor>, ScalarStatData>
 +{
 +  public:
 +    /** The base implementation. */
-         this->setInit();
++    typedef ScalarBase<StatStor> Base;
 +
 +    Scalar()
 +    {
- class Value
-     : public Wrap<Value,
-                   ValueBase,
-                   ScalarStatData>
++        this->doInit();
 +    }
 +
 +    /**
 +     * Sets the stat equal to the given value. Calls the base implementation
 +     * of operator=
 +     * @param v The new value.
 +     */
 +    template <typename U>
 +    void operator=(const U &v) { Base::operator=(v); }
 +};
 +
- template <class Bin = DefaultBin>
- class Average
-     : public Wrap<Average<Bin>,
-                   ScalarBase<AvgStor, Bin>,
-                   ScalarStatData>
++class Value : public Wrap<Value, ValueBase, ScalarStatData>
 +{
 +  public:
 +    /** The base implementation. */
 +    typedef ValueBase Base;
 +
 +    template <class T>
 +    Value &scalar(T &value)
 +    {
 +        Base::scalar(value);
 +        return *this;
 +    }
 +
 +    template <class T>
 +    Value &functor(T &func)
 +    {
 +        Base::functor(func);
 +        return *this;
 +    }
 +};
 +
 +/**
 + * A stat that calculates the per cycle average of a value.
 + * @sa Stat, ScalarBase, AvgStor
 + */
-     typedef ScalarBase<AvgStor, Bin> Base;
++template<int N = 0>
++class Average : public Wrap<Average<N>, ScalarBase<AvgStor>, ScalarStatData>
 +{
 +  public:
 +    /** The base implementation. */
-         this->setInit();
++    typedef ScalarBase<AvgStor> Base;
 +
 +    Average()
 +    {
- template <class Bin = DefaultBin>
- class Vector
-     : public WrapVec<Vector<Bin>,
-                      VectorBase<StatStor, Bin>,
-                      VectorStatData>
++        this->doInit();
 +    }
 +
 +    /**
 +     * Sets the stat equal to the given value. Calls the base implementation
 +     * of operator=
 +     * @param v The new value.
 +     */
 +    template <typename U>
 +    void operator=(const U &v) { Base::operator=(v); }
 +};
 +
 +/**
 + * A vector of scalar stats.
 + * @sa Stat, VectorBase, StatStor
 + */
-     typedef ScalarBase<StatStor, Bin> Base;
++template<int N = 0>
++class Vector : public WrapVec<Vector<N>, VectorBase<StatStor>, VectorStatData>
 +{
 +  public:
 +    /** The base implementation. */
-         this->bin.init(size, this->params);
-         this->setInit();
++    typedef ScalarBase<StatStor> Base;
 +
 +    /**
 +     * Set this vector to have the given size.
 +     * @param size The new size.
 +     * @return A reference to this stat.
 +     */
 +    Vector &init(size_t size) {
- template <class Bin = DefaultBin>
++        this->doInit(size);
 +        return *this;
 +    }
 +};
 +
 +/**
 + * A vector of Average stats.
 + * @sa Stat, VectorBase, AvgStor
 + */
-     : public WrapVec<AverageVector<Bin>,
-                      VectorBase<AvgStor, Bin>,
-                      VectorStatData>
++template<int N = 0>
 +class AverageVector
-         this->bin.init(size, this->params);
-         this->setInit();
++    : public WrapVec<AverageVector<N>, VectorBase<AvgStor>, VectorStatData>
 +{
 +  public:
 +    /**
 +     * Set this vector to have the given size.
 +     * @param size The new size.
 +     * @return A reference to this stat.
 +     */
 +    AverageVector &init(size_t size) {
- template <class Bin = DefaultBin>
++        this->doInit(size);
 +        return *this;
 +    }
 +};
 +
 +/**
 + * A 2-Dimensional vecto of scalar stats.
 + * @sa Stat, Vector2dBase, StatStor
 + */
-     : public WrapVec2d<Vector2d<Bin>,
-                        Vector2dBase<StatStor, Bin>,
-                        Vector2dStatData>
++template<int N = 0>
 +class Vector2d
-     Vector2d &init(size_t _x, size_t _y) {
-         this->statData()->x = this->x = _x;
-         this->statData()->y = this->y = _y;
-         this->bin.init(this->x * this->y, this->params);
-         this->setInit();
++    : public WrapVec2d<Vector2d<N>, Vector2dBase<StatStor>, Vector2dStatData>
 +{
 +  public:
- template <class Bin = DefaultBin>
++    Vector2d &init(size_t x, size_t y) {
++        this->doInit(x, y);
 +        return *this;
 +    }
 +};
 +
 +/**
 + * A simple distribution stat.
 + * @sa Stat, DistBase, DistStor
 + */
-     : public Wrap<Distribution<Bin>,
-                   DistBase<DistStor, Bin>,
-                   DistStatData>
++template<int N = 0>
 +class Distribution
-     typedef DistBase<DistStor, Bin> Base;
++    : public Wrap<Distribution<N>, DistBase<DistStor>, DistStatData>
 +{
 +  public:
 +    /** Base implementation. */
-     typedef typename DistStor::Params Params;
++    typedef DistBase<DistStor> Base;
 +    /** The Parameter type. */
-         this->bin.init(this->params);
-         this->setInit();
++    typedef DistStor::Params Params;
 +
 +  public:
 +    /**
 +     * Set the parameters of this distribution. @sa DistStor::Params
 +     * @param min The minimum value of the distribution.
 +     * @param max The maximum value of the distribution.
 +     * @param bkt The number of values in each bucket.
 +     * @return A reference to this distribution.
 +     */
 +    Distribution &init(Counter min, Counter max, Counter bkt) {
 +        this->params.min = min;
 +        this->params.max = max;
 +        this->params.bucket_size = bkt;
 +        this->params.size = (int)rint((max - min) / bkt + 1.0);
- template <class Bin = DefaultBin>
++        this->doInit();
 +        return *this;
 +    }
 +};
 +
 +/**
 + * Calculates the mean and variance of all the samples.
 + * @sa Stat, DistBase, FancyStor
 + */
-     : public Wrap<StandardDeviation<Bin>,
-                   DistBase<FancyStor, Bin>,
-                   DistStatData>
++template<int N = 0>
 +class StandardDeviation
-     typedef DistBase<DistStor, Bin> Base;
++    : public Wrap<StandardDeviation<N>, DistBase<FancyStor>, DistStatData>
 +{
 +  public:
 +    /** The base implementation */
-     typedef typename DistStor::Params Params;
++    typedef DistBase<DistStor> Base;
 +    /** The parameter type. */
-         this->bin.init(this->params);
-         this->setInit();
++    typedef DistStor::Params Params;
 +
 +  public:
 +    /**
 +     * Construct and initialize this distribution.
 +     */
 +    StandardDeviation() {
- template <class Bin = DefaultBin>
++        this->doInit();
 +    }
 +};
 +
 +/**
 + * Calculates the per cycle mean and variance of the samples.
 + * @sa Stat, DistBase, AvgFancy
 + */
-     : public Wrap<AverageDeviation<Bin>,
-                   DistBase<AvgFancy, Bin>,
-                   DistStatData>
++template<int N = 0>
 +class AverageDeviation
-     typedef DistBase<DistStor, Bin> Base;
++    : public Wrap<AverageDeviation<N>, DistBase<AvgFancy>, DistStatData>
 +{
 +  public:
 +    /** The base implementation */
-     typedef typename DistStor::Params Params;
++    typedef DistBase<DistStor> Base;
 +    /** The parameter type. */
-         this->bin.init(this->params);
-         this->setInit();
++    typedef DistStor::Params Params;
 +
 +  public:
 +    /**
 +     * Construct and initialize this distribution.
 +     */
 +    AverageDeviation()
 +    {
- template <class Bin = DefaultBin>
++        this->doInit();
 +    }
 +};
 +
 +/**
 + * A vector of distributions.
 + * @sa Stat, VectorDistBase, DistStor
 + */
-     : public WrapVec<VectorDistribution<Bin>,
-                      VectorDistBase<DistStor, Bin>,
++template<int N = 0>
 +class VectorDistribution
-     typedef VectorDistBase<DistStor, Bin> Base;
++    : public WrapVec<VectorDistribution<N>,
++                     VectorDistBase<DistStor>,
 +                     VectorDistStatData>
 +{
 +  public:
 +    /** The base implementation */
-     typedef typename DistStor::Params Params;
++    typedef VectorDistBase<DistStor> Base;
 +    /** The parameter type. */
-         this->bin.init(size, this->params);
-         this->setInit();
++    typedef DistStor::Params Params;
 +
 +  public:
 +    /**
 +     * Initialize storage and parameters for this distribution.
 +     * @param size The size of the vector (the number of distributions).
 +     * @param min The minimum value of the distribution.
 +     * @param max The maximum value of the distribution.
 +     * @param bkt The number of values in each bucket.
 +     * @return A reference to this distribution.
 +     */
 +    VectorDistribution &init(int size, Counter min, Counter max, Counter bkt) {
 +        this->params.min = min;
 +        this->params.max = max;
 +        this->params.bucket_size = bkt;
 +        this->params.size = (int)rint((max - min) / bkt + 1.0);
- template <class Bin = DefaultBin>
++        this->doInit(size);
 +        return *this;
 +    }
 +};
 +
 +/**
 + * This is a vector of StandardDeviation stats.
 + * @sa Stat, VectorDistBase, FancyStor
 + */
-     : public WrapVec<VectorStandardDeviation<Bin>,
-                      VectorDistBase<FancyStor, Bin>,
++template<int N = 0>
 +class VectorStandardDeviation
-     typedef VectorDistBase<FancyStor, Bin> Base;
++    : public WrapVec<VectorStandardDeviation<N>,
++                     VectorDistBase<FancyStor>,
 +                     VectorDistStatData>
 +{
 +  public:
 +    /** The base implementation */
-     typedef typename DistStor::Params Params;
++    typedef VectorDistBase<FancyStor> Base;
 +    /** The parameter type. */
-         this->bin.init(size, this->params);
-         this->setInit();
++    typedef DistStor::Params Params;
 +
 +  public:
 +    /**
 +     * Initialize storage for this distribution.
 +     * @param size The size of the vector.
 +     * @return A reference to this distribution.
 +     */
 +    VectorStandardDeviation &init(int size) {
- template <class Bin = DefaultBin>
++        this->doInit(size);
 +        return *this;
 +    }
 +};
 +
 +/**
 + * This is a vector of AverageDeviation stats.
 + * @sa Stat, VectorDistBase, AvgFancy
 + */
-     : public WrapVec<VectorAverageDeviation<Bin>,
-                      VectorDistBase<AvgFancy, Bin>,
++template<int N = 0>
 +class VectorAverageDeviation
-     typedef VectorDistBase<AvgFancy, Bin> Base;
++    : public WrapVec<VectorAverageDeviation<N>,
++                     VectorDistBase<AvgFancy>,
 +                     VectorDistStatData>
 +{
 +  public:
 +    /** The base implementation */
-     typedef typename DistStor::Params Params;
++    typedef VectorDistBase<AvgFancy> Base;
 +    /** The parameter type. */
-         this->bin.init(size, this->params);
-         this->setInit();
++    typedef DistStor::Params Params;
 +
 +  public:
 +    /**
 +     * Initialize storage for this distribution.
 +     * @param size The size of the vector.
 +     * @return A reference to this distribution.
 +     */
 +    VectorAverageDeviation &init(int size) {
-     /**
-      * Return true if Formula is binned. i.e. any of its children
-      * nodes are binned
-      * @return True if Formula is binned.
-      */
-     bool binned() const;
++        this->doInit(size);
 +        return *this;
 +    }
 +};
 +
 +/**
 + * A formula for statistics that is calculated when printed. A formula is
 + * stored as a tree of Nodes that represent the equation to calculate.
 + * @sa Stat, ScalarStat, VectorStat, Node, Temp
 + */
 +class FormulaBase : public DataAccess
 +{
 +  protected:
 +    /** The root of the tree which represents the Formula */
 +    NodePtr root;
 +    friend class Temp;
 +
 +  public:
 +    /**
 +     * Return the result of the Fomula in a vector.  If there were no Vector
 +     * components to the Formula, then the vector is size 1.  If there were,
 +     * like x/y with x being a vector of size 3, then the result returned will
 +     * be x[0]/y, x[1]/y, x[2]/y, respectively.
 +     * @return The result vector.
 +     */
 +    void result(VResult &vec) const;
 +
 +    /**
 +     * Return the total Formula result.  If there is a Vector
 +     * component to this Formula, then this is the result of the
 +     * Formula if the formula is applied after summing all the
 +     * components of the Vector.  For example, if Formula is x/y where
 +     * x is size 3, then total() will return (x[1]+x[2]+x[3])/y.  If
 +     * there is no Vector component, total() returns the same value as
 +     * the first entry in the VResult val() returns.
 +     * @return The total of the result vector.
 +     */
 +    Result total() const;
 +
 +    /**
 +     * Return the number of elements in the tree.
 +     */
 +    size_t size() const;
 +
-     virtual bool binned() const { return s.binned(); }
 +    bool check() const { return true; }
 +
 +    /**
 +     * Formulas don't need to be reset
 +     */
 +    void reset();
 +
 +    /**
 +     *
 +     */
 +    bool zero() const;
 +
 +    /**
 +     *
 +     */
 +    void update(StatData *);
 +
 +    std::string str() const;
 +};
 +
 +class FormulaData : public VectorData
 +{
 +  public:
 +    virtual std::string str() const = 0;
 +    virtual bool check() const { return true; }
 +};
 +
 +template <class Stat>
 +class FormulaStatData : public FormulaData
 +{
 +  protected:
 +    Stat &s;
 +    mutable VResult vec;
 +    mutable VCounter cvec;
 +
 +  public:
 +    FormulaStatData(Stat &stat) : s(stat) {}
 +
-     virtual bool binned() const { return formula.binned(); }
 +    virtual bool zero() const { return s.zero(); }
 +    virtual void reset() { s.reset(); }
 +
 +    virtual size_t size() const { return s.size(); }
 +    virtual const VResult &result() const
 +    {
 +        s.result(vec);
 +        return vec;
 +    }
 +    virtual Result total() const { return s.total(); }
 +    virtual VCounter &value() const { return cvec; }
 +    virtual void visit(Visit &visitor)
 +    {
 +        update();
 +        s.update(this);
 +        visitor.visit(*this);
 +    }
 +    virtual std::string str() const { return s.str(); }
 +};
 +
 +class Temp;
 +class Formula
 +    : public WrapVec<Formula,
 +                     FormulaBase,
 +                     FormulaStatData>
 +{
 +  public:
 +    /**
 +     * Create and initialize thie formula, and register it with the database.
 +     */
 +    Formula();
 +
 +    /**
 +     * Create a formula with the given root node, register it with the
 +     * database.
 +     * @param r The root of the expression tree.
 +     */
 +    Formula(Temp r);
 +
 +    /**
 +     * Set an unitialized Formula to the given root.
 +     * @param r The root of the expression tree.
 +     * @return a reference to this formula.
 +     */
 +    const Formula &operator=(Temp r);
 +
 +    /**
 +     * Add the given tree to the existing one.
 +     * @param r The root of the expression tree.
 +     * @return a reference to this formula.
 +     */
 +    const Formula &operator+=(Temp r);
 +};
 +
 +class FormulaNode : public Node
 +{
 +  private:
 +    const Formula &formula;
 +    mutable VResult vec;
 +
 +  public:
 +    FormulaNode(const Formula &f) : formula(f) {}
 +
 +    virtual size_t size() const { return formula.size(); }
 +    virtual const VResult &result() const { formula.result(vec); return vec; }
 +    virtual Result total() const { return formula.total(); }
-     template <class Bin>
-     Temp(const Scalar<Bin> &s)
 +
 +    virtual std::string str() const { return formula.str(); }
 +};
 +
 +/**
 + * Helper class to construct formula node trees.
 + */
 +class Temp
 +{
 +  protected:
 +    /**
 +     * Pointer to a Node object.
 +     */
 +    NodePtr node;
 +
 +  public:
 +    /**
 +     * Copy the given pointer to this class.
 +     * @param n A pointer to a Node object to copy.
 +     */
 +    Temp(NodePtr n) : node(n) { }
 +
 +    /**
 +     * Return the node pointer.
 +     * @return the node pointer.
 +     */
 +    operator NodePtr&() { return node;}
 +
 +  public:
 +    /**
 +     * Create a new ScalarStatNode.
 +     * @param s The ScalarStat to place in a node.
 +     */
-     template <class Bin>
-     Temp(const Average<Bin> &s)
++    template <int N>
++    Temp(const Scalar<N> &s)
 +        : node(new ScalarStatNode(s.statData())) { }
 +
 +    /**
 +     * Create a new ScalarStatNode.
 +     * @param s The ScalarStat to place in a node.
 +     */
 +    Temp(const Value &s)
 +        : node(new ScalarStatNode(s.statData())) { }
 +
 +    /**
 +     * Create a new ScalarStatNode.
 +     * @param s The ScalarStat to place in a node.
 +     */
-     template <class Bin>
-     Temp(const Vector<Bin> &s)
++    template <int N>
++    Temp(const Average<N> &s)
 +        : node(new ScalarStatNode(s.statData())) { }
 +
 +    /**
 +     * Create a new VectorStatNode.
 +     * @param s The VectorStat to place in a node.
 +     */
-     template <class Storage, class Bin>
-     Temp(const ScalarProxy<Storage, Bin> &p)
-         : node(new ScalarProxyNode<Storage, Bin>(p)) { }
++    template <int N>
++    Temp(const Vector<N> &s)
 +        : node(new VectorStatNode(s.statData())) { }
 +
 +    /**
 +     *
 +     */
 +    Temp(const Formula &f)
 +        : node(new FormulaNode(f)) { }
 +
 +    /**
 +     * Create a new ScalarProxyNode.
 +     * @param p The ScalarProxy to place in a node.
 +     */
++    template <class Stat>
++    Temp(const ScalarProxy<Stat> &p)
++        : node(new ScalarProxyNode<Stat>(p)) { }
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(signed char value)
 +        : node(new ConstNode<signed char>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(unsigned char value)
 +        : node(new ConstNode<unsigned char>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(signed short value)
 +        : node(new ConstNode<signed short>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(unsigned short value)
 +        : node(new ConstNode<unsigned short>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(signed int value)
 +        : node(new ConstNode<signed int>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(unsigned int value)
 +        : node(new ConstNode<unsigned int>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(signed long value)
 +        : node(new ConstNode<signed long>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(unsigned long value)
 +        : node(new ConstNode<unsigned long>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(signed long long value)
 +        : node(new ConstNode<signed long long>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(unsigned long long value)
 +        : node(new ConstNode<unsigned long long>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(float value)
 +        : node(new ConstNode<float>(value)) {}
 +
 +    /**
 +     * Create a ConstNode
 +     * @param value The value of the const node.
 +     */
 +    Temp(double value)
 +        : node(new ConstNode<double>(value)) {}
 +};
 +
 +
 +/**
 + * @}
 + */
 +
 +void check();
 +void reset();
 +void registerResetCallback(Callback *cb);
 +
 +inline Temp
 +operator+(Temp l, Temp r)
 +{
 +    return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
 +}
 +
 +inline Temp
 +operator-(Temp l, Temp r)
 +{
 +    return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
 +}
 +
 +inline Temp
 +operator*(Temp l, Temp r)
 +{
 +    return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
 +}
 +
 +inline Temp
 +operator/(Temp l, Temp r)
 +{
 +    return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
 +}
 +
 +inline Temp
 +operator-(Temp l)
 +{
 +    return NodePtr(new UnaryNode<std::negate<Result> >(l));
 +}
 +
 +template <typename T>
 +inline Temp
 +constant(T val)
 +{
 +    return NodePtr(new ConstNode<T>(val));
 +}
 +
 +inline Temp
 +sum(Temp val)
 +{
 +    return NodePtr(new SumNode<std::plus<Result> >(val));
 +}
 +
 +/* namespace Stats */ }
 +
 +#endif // __BASE_STATISTICS_HH__
index fa4bcd5ee0bfc7f6d9b8cbdf633210d2fdba34c9,0000000000000000000000000000000000000000..0fb31f4ce9dca55e2a944acaa83c6aecb8e2e2db
mode 100644,000000..100644
--- /dev/null
@@@ -1,902 -1,0 +1,828 @@@
-     mysql.query("DELETE bins "
-                 "FROM bins "
-                 "LEFT JOIN data ON bn_id=dt_bin "
-                 "WHERE dt_bin IS NULL");
-     if (mysql.commit())
-         panic("could not commit transaction\n%s\n", mysql.error);
 +/*
 + * 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
 + * 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 <cassert>
 +#include <map>
 +#include <sstream>
 +#include <string>
 +#include <vector>
 +
 +#include "base/misc.hh"
 +#include "base/mysql.hh"
 +#include "base/statistics.hh"
 +#include "base/stats/flags.hh"
 +#include "base/stats/mysql.hh"
 +#include "base/stats/mysql_run.hh"
 +#include "base/stats/statdb.hh"
 +#include "base/stats/types.hh"
 +#include "base/str.hh"
 +#include "sim/host.hh"
 +
 +using namespace std;
 +
 +namespace Stats {
 +
 +MySqlRun MySqlDB;
 +
 +bool
 +MySqlConnected()
 +{
 +    return MySqlDB.connected();
 +}
 +
 +void
 +MySqlRun::connect(const string &host, const string &user, const string &passwd,
 +                  const string &db, const string &name, const string &sample,
 +                  const string &project)
 +{
 +    if (connected())
 +        panic("can only get one database connection at this time!");
 +
 +    mysql.connect(host, user, passwd, db);
 +    if (mysql.error)
 +        panic("could not connect to database server\n%s\n", mysql.error);
 +
 +    if (mysql.autocommit(false))
 +        panic("could not set autocommit\n%s\n", mysql.error);
 +
 +    remove(name);
 +    //cleanup();
 +    setup(name, sample, user, project);
 +}
 +
 +void
 +MySqlRun::setup(const string &name, const string &sample, const string &user,
 +                const string &project)
 +{
 +    assert(mysql.connected());
 +
 +    stringstream insert;
 +    ccprintf(insert,
 +             "INSERT INTO "
 +             "runs(rn_name,rn_sample,rn_user,rn_project,rn_date,rn_expire)"
 +             "values(\"%s\", \"%s\", \"%s\", \"%s\", NOW(),"
 +             "DATE_ADD(CURDATE(), INTERVAL 31 DAY))",
 +             name, sample, user, project);
 +
 +    mysql.query(insert);
 +    if (mysql.error)
 +        panic("could not get a run\n%s\n", mysql.error);
 +
 +    run_id = mysql.insert_id();
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +}
 +
 +void
 +MySqlRun::remove(const string &name)
 +{
 +    assert(mysql.connected());
 +    stringstream sql;
 +    ccprintf(sql, "DELETE FROM runs WHERE rn_name=\"%s\"", name);
 +    mysql.query(sql);
 +    if (mysql.error)
 +        panic("could not delete run\n%s\n", mysql.error);
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +}
 +
 +void
 +MySqlRun::cleanup()
 +{
 +    assert(mysql.connected());
 +
 +    mysql.query("DELETE data "
 +                "FROM data "
 +                "LEFT JOIN runs ON dt_run=rn_id "
 +                "WHERE rn_id IS NULL");
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +
 +    mysql.query("DELETE formula_ref "
 +                "FROM formula_ref "
 +                "LEFT JOIN runs ON fr_run=rn_id "
 +                "WHERE rn_id IS NULL");
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +
 +    mysql.query("DELETE formulas "
 +                "FROM formulas "
 +                "LEFT JOIN formula_ref ON fm_stat=fr_stat "
 +                "WHERE fr_stat IS NULL");
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +
 +    mysql.query("DELETE stats "
 +                "FROM stats "
 +                "LEFT JOIN data ON st_id=dt_stat "
 +                "WHERE dt_stat IS NULL");
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +
 +    mysql.query("DELETE subdata "
 +                "FROM subdata "
 +                "LEFT JOIN data ON sd_stat=dt_stat "
 +                "WHERE dt_stat IS NULL");
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +
- unsigned
- SetupBin(const string &bin)
- {
-     static map<string, int> binmap;
-     using namespace MySQL;
-     map<string,int>::const_iterator i = binmap.find(bin);
-     if (i != binmap.end())
-         return (*i).second;
-     Connection &mysql = MySqlDB.conn();
-     assert(mysql.connected());
-     uint16_t bin_id;
-     stringstream select;
-     stringstream insert;
-     ccprintf(select, "SELECT bn_id FROM bins WHERE bn_name=\"%s\"", bin);
-     mysql.query(select);
-     MySQL::Result result = mysql.store_result();
-     if (result) {
-         assert(result.num_fields() == 1);
-         MySQL::Row row = result.fetch_row();
-         if (row) {
-             to_number(row[0], bin_id);
-             goto exit;
-         }
-     }
-     ccprintf(insert, "INSERT INTO bins(bn_name) values(\"%s\")", bin);
-     mysql.query(insert);
-     if (mysql.error)
-         panic("could not get a bin\n%s\n", mysql.error);
-     bin_id = mysql.insert_id();
-     if (mysql.commit())
-         panic("could not commit transaction\n%s\n", mysql.error);
-     binmap.insert(make_pair(bin, bin_id));
-   exit:
-     return bin_id;
- }
 +    mysql.query("DELETE events"
 +                "FROM events"
 +                "LEFT JOIN runs ON ev_run=rn_id"
 +                "WHERE rn_id IS NULL");
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +
 +    mysql.query("DELETE event_names"
 +                "FROM event_names"
 +                "LEFT JOIN events ON en_id=ev_event"
 +                "WHERE ev_event IS NULL");
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +}
 +
 +void
 +SetupStat::init()
 +{
 +    name = "";
 +    descr = "";
 +    type = "";
 +    print = false;
 +    prereq = 0;
 +    prec = -1;
 +    nozero = false;
 +    nonan = false;
 +    total = false;
 +    pdf = false;
 +    cdf = false;
 +    min = 0;
 +    max = 0;
 +    bktsize = 0;
 +    size = 0;
 +}
 +
 +unsigned
 +SetupStat::setup()
 +{
 +    MySQL::Connection &mysql = MySqlDB.conn();
 +
 +    stringstream insert;
 +    ccprintf(insert,
 +             "INSERT INTO "
 +             "stats(st_name, st_descr, st_type, st_print, st_prereq, "
 +             "st_prec, st_nozero, st_nonan, st_total, st_pdf, st_cdf, "
 +             "st_min, st_max, st_bktsize, st_size)"
 +             "values(\"%s\",\"%s\",\"%s\","
 +             "        %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
 +             name, descr, type, print, prereq, (int)prec, nozero, nonan,
 +             total, pdf, cdf,
 +             min, max, bktsize, size);
 +
 +    mysql.query(insert);
 +    if (!mysql.error) {
 +        int id = mysql.insert_id();
 +        if (mysql.commit())
 +            panic("could not commit transaction\n%s\n", mysql.error);
 +        return id;
 +    }
 +
 +    stringstream select;
 +    ccprintf(select, "SELECT * FROM stats WHERE st_name=\"%s\"", name);
 +
 +    mysql.query(select);
 +    MySQL::Result result = mysql.store_result();
 +    if (!result)
 +        panic("could not find stat\n%s\n", mysql.error);
 +
 +    assert(result.num_fields() == 16);
 +    MySQL::Row row = result.fetch_row();
 +    if (!row)
 +        panic("could not get stat row\n%s\n", mysql.error);
 +
 +    bool tb;
 +    int8_t ti8;
 +    uint16_t tu16;
 +    int64_t ti64;
 +    uint64_t tu64;
 +
 +    if (name != (char *)row[1])
 +        panic("failed stat check on %s:name. %s != %s\n",
 +              name, name, row[1]);
 +
 +    if (descr != (char *)row[2])
 +        panic("failed stat check on %s:descr. %s != %s\n",
 +              name, descr, row[2]);
 +
 +    if (type != (char *)row[3])
 +        panic("failed stat check on %s:type. %s != %s\n",
 +              name, type, row[3]);
 +
 +    if (!to_number(row[4], tb) || print != tb)
 +        panic("failed stat check on %s:print. %d != %d\n",
 +              name, print, tb);
 +
 +    if (!to_number(row[6], ti8) || prec != ti8)
 +        panic("failed stat check on %s:prec. %d != %d\n",
 +              name, prec, ti8);
 +
 +    if (!to_number(row[7], tb) || nozero != tb)
 +        panic("failed stat check on %s:nozero. %d != %d\n",
 +              name, nozero, tb);
 +
 +    if (!to_number(row[8], tb) || nonan != tb)
 +        panic("failed stat check on %s:nonan. %d != %d\n",
 +              name, nonan, tb);
 +
 +    if (!to_number(row[9], tb) || total != tb)
 +        panic("failed stat check on %s:total. %d != %d\n",
 +              name, total, tb);
 +
 +    if (!to_number(row[10], tb) || pdf != tb)
 +        panic("failed stat check on %s:pdf. %d != %d\n",
 +              name, pdf, tb);
 +
 +    if (!to_number(row[11], tb) || cdf != tb)
 +        panic("failed stat check on %s:cdf. %d != %d\n",
 +              name, cdf, tb);
 +
 +    if (!to_number(row[12], ti64) || min != ti64)
 +        panic("failed stat check on %s:min. %d != %d\n",
 +              name, min, ti64);
 +
 +    if (!to_number(row[13], ti64) || max != ti64)
 +        panic("failed stat check on %s:max. %d != %d\n",
 +              name, max, ti64);
 +
 +    if (!to_number(row[14], tu64) || bktsize != tu64)
 +        panic("failed stat check on %s:bktsize. %d != %d\n",
 +              name, bktsize, tu64);
 +
 +    if (!to_number(row[15], tu16) || size != tu16)
 +        panic("failed stat check on %s:size. %d != %d\n",
 +              name, size, tu16);
 +
 +    to_number(row[5], prereq);
 +    uint16_t statid;
 +    to_number(row[0], statid);
 +    return statid;
 +}
 +
-            "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_bin,dt_data) "
 +InsertData::InsertData()
 +{
 +    query = new char[maxsize + 1];
 +    size = 0;
 +    flush();
 +}
 +
 +InsertData::~InsertData()
 +{
 +    delete [] query;
 +}
 +
 +void
 +InsertData::flush()
 +{
 +    if (size) {
 +        MySQL::Connection &mysql = MySqlDB.conn();
 +        assert(mysql.connected());
 +        mysql.query(query);
 +        if (mysql.error)
 +            panic("could not insert data\n%s\n", mysql.error);
 +        if (mysql.commit())
 +            panic("could not commit transaction\n%s\n", mysql.error);
 +    }
 +
 +    query[0] = '\0';
 +    size = 0;
 +    first = true;
 +    strcpy(query, "INSERT INTO "
-     size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")",
++           "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_data) "
 +           "values");
 +    size = strlen(query);
 +}
 +
 +void
 +InsertData::insert()
 +{
 +    if (size + 1024 > maxsize)
 +        flush();
 +
 +    if (!first) {
 +        query[size++] = ',';
 +        query[size] = '\0';
 +    }
 +
 +    first = false;
 +
-                     bin, data);
++    size += sprintf(query + size, "(%u,%d,%d,%u,%llu,\"%f\")",
 +                    stat, x, y, MySqlDB.run(), (unsigned long long)tick,
- void
- MySql::output(MainBin *bin)
- {
-     MySQL::Connection &mysql = MySqlDB.conn();
-     if (bin) {
-         bin->activate();
-         newdata.bin = SetupBin(bin->name());
-     } else {
-         newdata.bin = 0;
-     }
-     Database::stat_list_t::const_iterator i, end = Database::stats().end();
-     for (i = Database::stats().begin(); i != end; ++i) {
-         StatData *stat = *i;
-         if (bin && stat->binned() || !bin && !stat->binned()) {
-             stat->visit(*this);
-             if (mysql.commit())
-                 panic("could not commit transaction\n%s\n", mysql.error);
-         }
-     }
- }
++                    data);
 +}
 +
 +struct InsertSubData
 +{
 +    uint16_t stat;
 +    int16_t x;
 +    int16_t y;
 +    string name;
 +    string descr;
 +
 +    void setup();
 +};
 +
 +void
 +InsertSubData::setup()
 +{
 +    MySQL::Connection &mysql = MySqlDB.conn();
 +    assert(mysql.connected());
 +    stringstream insert;
 +    ccprintf(insert,
 +             "INSERT INTO subdata(sd_stat,sd_x,sd_y,sd_name,sd_descr) "
 +             "values(%d,%d,%d,\"%s\",\"%s\")",
 +             stat, x, y, name, descr);
 +
 +    mysql.query(insert);
 +//    if (mysql.error)
 +//    panic("could not insert subdata\n%s\n", mysql.error);
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +}
 +
 +void
 +InsertFormula(uint16_t stat, const string &formula)
 +{
 +    MySQL::Connection &mysql = MySqlDB.conn();
 +    assert(mysql.connected());
 +    stringstream insert_formula;
 +    ccprintf(insert_formula,
 +             "INSERT INTO formulas(fm_stat,fm_formula) values(%d, \"%s\")",
 +             stat, formula);
 +
 +    mysql.query(insert_formula);
 +//    if (mysql.error)
 +//    panic("could not insert formula\n%s\n", mysql.error);
 +
 +    stringstream insert_ref;
 +    ccprintf(insert_ref,
 +             "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)",
 +             stat, MySqlDB.run());
 +
 +    mysql.query(insert_ref);
 +//    if (mysql.error)
 +//    panic("could not insert formula reference\n%s\n", mysql.error);
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +}
 +
 +void
 +UpdatePrereq(uint16_t stat, uint16_t prereq)
 +{
 +    MySQL::Connection &mysql = MySqlDB.conn();
 +    assert(mysql.connected());
 +    stringstream update;
 +    ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d",
 +             prereq, stat);
 +    mysql.query(update);
 +    if (mysql.error)
 +        panic("could not update prereq\n%s\n", mysql.error);
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +}
 +
 +void
 +MySql::configure()
 +{
 +    /*
 +     * set up all stats!
 +     */
 +    using namespace Database;
 +
 +    MySQL::Connection &mysql = MySqlDB.conn();
 +
 +    stat_list_t::const_iterator i, end = stats().end();
 +    for (i = stats().begin(); i != end; ++i) {
 +        (*i)->visit(*this);
 +    }
 +
 +    for (i = stats().begin(); i != end; ++i) {
 +        StatData *data = *i;
 +        if (data->prereq) {
 +            uint16_t stat_id = find(data->id);
 +            uint16_t prereq_id = find(data->prereq->id);
 +            assert(stat_id && prereq_id);
 +
 +            UpdatePrereq(stat_id, prereq_id);
 +        }
 +    }
 +
 +    if (mysql.commit())
 +        panic("could not commit transaction\n%s\n", mysql.error);
 +
 +    configured = true;
 +}
 +
 +
 +bool
 +MySql::configure(const StatData &data, string type)
 +{
 +    stat.init();
 +    stat.name = data.name;
 +    stat.descr = data.desc;
 +    stat.type = type;
 +    stat.print = data.flags & print;
 +    stat.prec = data.precision;
 +    stat.nozero = data.flags & nozero;
 +    stat.nonan = data.flags & nonan;
 +    stat.total = data.flags & total;
 +    stat.pdf = data.flags & pdf;
 +    stat.cdf = data.flags & cdf;
 +
 +    return stat.print;
 +}
 +
 +void
 +MySql::configure(const ScalarData &data)
 +{
 +    if (!configure(data, "SCALAR"))
 +        return;
 +
 +    insert(data.id, stat.setup());
 +}
 +
 +void
 +MySql::configure(const VectorData &data)
 +{
 +    if (!configure(data, "VECTOR"))
 +        return;
 +
 +    uint16_t statid = stat.setup();
 +
 +    if (!data.subnames.empty()) {
 +        InsertSubData subdata;
 +        subdata.stat = statid;
 +        subdata.y = 0;
 +        for (int i = 0; i < data.subnames.size(); ++i) {
 +            subdata.x = i;
 +            subdata.name = data.subnames[i];
 +            subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
 +
 +            if (!subdata.name.empty() || !subdata.descr.empty())
 +                subdata.setup();
 +        }
 +    }
 +
 +    insert(data.id, statid);
 +}
 +
 +void
 +MySql::configure(const DistData &data)
 +{
 +    if (!configure(data, "DIST"))
 +        return;
 +
 +    if (!data.data.fancy) {
 +        stat.size = data.data.size;
 +        stat.min = data.data.min;
 +        stat.max = data.data.max;
 +        stat.bktsize = data.data.bucket_size;
 +    }
 +    insert(data.id, stat.setup());
 +}
 +
 +void
 +MySql::configure(const VectorDistData &data)
 +{
 +    if (!configure(data, "VECTORDIST"))
 +        return;
 +
 +    if (!data.data[0].fancy) {
 +        stat.size = data.data[0].size;
 +        stat.min = data.data[0].min;
 +        stat.max = data.data[0].max;
 +        stat.bktsize = data.data[0].bucket_size;
 +    }
 +
 +    uint16_t statid = stat.setup();
 +
 +    if (!data.subnames.empty()) {
 +        InsertSubData subdata;
 +        subdata.stat = statid;
 +        subdata.y = 0;
 +        for (int i = 0; i < data.subnames.size(); ++i) {
 +            subdata.x = i;
 +            subdata.name = data.subnames[i];
 +            subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
 +            if (!subdata.name.empty() || !subdata.descr.empty())
 +                subdata.setup();
 +        }
 +    }
 +
 +    insert(data.id, statid);
 +}
 +
 +void
 +MySql::configure(const Vector2dData &data)
 +{
 +    if (!configure(data, "VECTOR2D"))
 +        return;
 +
 +    uint16_t statid = stat.setup();
 +
 +    if (!data.subnames.empty()) {
 +        InsertSubData subdata;
 +        subdata.stat = statid;
 +        subdata.y = -1;
 +        for (int i = 0; i < data.subnames.size(); ++i) {
 +            subdata.x = i;
 +            subdata.name = data.subnames[i];
 +            subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i];
 +            if (!subdata.name.empty() || !subdata.descr.empty())
 +                subdata.setup();
 +        }
 +    }
 +
 +    if (!data.y_subnames.empty()) {
 +        InsertSubData subdata;
 +        subdata.stat = statid;
 +        subdata.x = -1;
 +        subdata.descr = "";
 +        for (int i = 0; i < data.y_subnames.size(); ++i) {
 +            subdata.y = i;
 +            subdata.name = data.y_subnames[i];
 +            if (!subdata.name.empty())
 +                subdata.setup();
 +        }
 +    }
 +
 +    insert(data.id, statid);
 +}
 +
 +void
 +MySql::configure(const FormulaData &data)
 +{
 +    configure(data, "FORMULA");
 +    insert(data.id, stat.setup());
 +    InsertFormula(find(data.id), data.str());
 +}
 +
-     output(NULL);
-     if (!bins().empty()) {
-         bin_list_t::iterator i, end = bins().end();
-         for (i = bins().begin(); i != end; ++i)
-             output(*i);
 +bool
 +MySql::valid() const
 +{
 +    return MySqlDB.connected();
 +}
 +
 +void
 +MySql::output()
 +{
 +    using namespace Database;
 +    assert(valid());
 +
 +    if (!configured)
 +        configure();
 +
 +    // store sample #
 +    newdata.tick = curTick;
 +
++    MySQL::Connection &mysql = MySqlDB.conn();
++
++    Database::stat_list_t::const_iterator i, end = Database::stats().end();
++    for (i = Database::stats().begin(); i != end; ++i) {
++        StatData *stat = *i;
++        stat->visit(*this);
++        if (mysql.commit())
++            panic("could not commit transaction\n%s\n", mysql.error);
 +    }
 +
 +    newdata.flush();
 +}
 +
 +void
 +MySql::output(const ScalarData &data)
 +{
 +    if (!(data.flags & print))
 +        return;
 +
 +    newdata.stat = find(data.id);
 +    newdata.x = 0;
 +    newdata.y = 0;
 +    newdata.data = data.value();
 +
 +    newdata.insert();
 +}
 +
 +void
 +MySql::output(const VectorData &data)
 +{
 +    if (!(data.flags & print))
 +        return;
 +
 +    newdata.stat = find(data.id);
 +    newdata.y = 0;
 +
 +    const VCounter &cvec = data.value();
 +    int size = data.size();
 +    for (int x = 0; x < size; x++) {
 +        newdata.x = x;
 +        newdata.data = cvec[x];
 +        newdata.insert();
 +    }
 +}
 +
 +void
 +MySql::output(const DistDataData &data)
 +{
 +    const int db_sum = -1;
 +    const int db_squares = -2;
 +    const int db_samples = -3;
 +    const int db_min_val = -4;
 +    const int db_max_val = -5;
 +    const int db_underflow = -6;
 +    const int db_overflow = -7;
 +
 +    newdata.x = db_sum;
 +    newdata.data = data.sum;
 +    newdata.insert();
 +
 +    newdata.x = db_squares;
 +    newdata.data = data.squares;
 +    newdata.insert();
 +
 +    newdata.x = db_samples;
 +    newdata.data = data.samples;
 +    newdata.insert();
 +
 +    if (data.samples && !data.fancy) {
 +        newdata.x = db_min_val;
 +        newdata.data = data.min_val;
 +        newdata.insert();
 +
 +        newdata.x = db_max_val;
 +        newdata.data = data.max_val;
 +        newdata.insert();
 +
 +        newdata.x = db_underflow;
 +        newdata.data = data.underflow;
 +        newdata.insert();
 +
 +        newdata.x = db_overflow;
 +        newdata.data = data.overflow;
 +        newdata.insert();
 +
 +        int size = data.cvec.size();
 +        for (int x = 0; x < size; x++) {
 +            newdata.x = x;
 +            newdata.data = data.cvec[x];
 +            newdata.insert();
 +        }
 +    }
 +}
 +
 +
 +void
 +MySql::output(const DistData &data)
 +{
 +    if (!(data.flags & print))
 +        return;
 +
 +    newdata.stat = find(data.id);
 +    newdata.y = 0;
 +    output(data.data);
 +}
 +
 +void
 +MySql::output(const VectorDistData &data)
 +{
 +    if (!(data.flags & print))
 +        return;
 +
 +    newdata.stat = find(data.id);
 +
 +    int size = data.data.size();
 +    for (int y = 0; y < size; ++y) {
 +        newdata.y = y;
 +        output(data.data[y]);
 +    }
 +}
 +
 +void
 +MySql::output(const Vector2dData &data)
 +{
 +    if (!(data.flags & print))
 +        return;
 +
 +    newdata.stat = find(data.id);
 +
 +    int index = 0;
 +    for (int x = 0; x < data.x; x++) {
 +        newdata.x = x;
 +        for (int y = 0; y < data.y; y++) {
 +            newdata.y = y;
 +            newdata.data = data.cvec[index++];
 +            newdata.insert();
 +        }
 +    }
 +}
 +
 +void
 +MySql::output(const FormulaData &data)
 +{
 +}
 +
 +/*
 + * Implement the visitor
 + */
 +void
 +MySql::visit(const ScalarData &data)
 +{
 +    if (!configured)
 +        configure(data);
 +    else
 +        output(data);
 +}
 +
 +void
 +MySql::visit(const VectorData &data)
 +{
 +    if (!configured)
 +        configure(data);
 +    else
 +        output(data);
 +}
 +
 +void
 +MySql::visit(const DistData &data)
 +{
 +    return;
 +    if (!configured)
 +        configure(data);
 +    else
 +        output(data);
 +}
 +
 +void
 +MySql::visit(const VectorDistData &data)
 +{
 +    return;
 +    if (!configured)
 +        configure(data);
 +    else
 +        output(data);
 +}
 +
 +void
 +MySql::visit(const Vector2dData &data)
 +{
 +    return;
 +    if (!configured)
 +        configure(data);
 +    else
 +        output(data);
 +}
 +
 +void
 +MySql::visit(const FormulaData &data)
 +{
 +    if (!configured)
 +        configure(data);
 +    else
 +        output(data);
 +}
 +
 +/* namespace Stats */ }
index 1d88fbcd9672d2b870b3110bb367a6aa1f6c8e5b,0000000000000000000000000000000000000000..50f7d9e9792f30a0117ee7769383836face53e8e
mode 100644,000000..100644
--- /dev/null
@@@ -1,157 -1,0 +1,154 @@@
- class MainBin;
 +/*
 + * 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
 + * 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
 + */
 +
 +#ifndef __BASE_STATS_MYSQL_HH__
 +#define __BASE_STATS_MYSQL_HH__
 +
 +#include <map>
 +#include <string>
 +
 +#include "base/stats/output.hh"
 +
 +namespace MySQL { class Connection; }
 +namespace Stats {
 +
-     uint16_t bin;
 +class DistDataData;
 +class MySqlRun;
 +bool MySqlConnected();
 +extern MySqlRun MySqlDB;
 +
 +struct SetupStat
 +{
 +    std::string name;
 +    std::string descr;
 +    std::string type;
 +    bool print;
 +    uint16_t prereq;
 +    int8_t prec;
 +    bool nozero;
 +    bool nonan;
 +    bool total;
 +    bool pdf;
 +    bool cdf;
 +    double min;
 +    double max;
 +    double bktsize;
 +    uint16_t size;
 +
 +    void init();
 +    unsigned setup();
 +};
 +
 +class InsertData
 +{
 +  private:
 +    char *query;
 +    int size;
 +    bool first;
 +    static const int maxsize = 1024*1024;
 +
 +  public:
 +    MySqlRun *run;
 +
 +  public:
 +    uint64_t tick;
 +    double data;
 +    uint16_t stat;
-     void output(MainBin *bin);
 +    int16_t x;
 +    int16_t y;
 +
 +  public:
 +    InsertData();
 +    ~InsertData();
 +
 +    void flush();
 +    void insert();
 +};
 +
 +class MySql : public Output
 +{
 +  protected:
 +    SetupStat stat;
 +    InsertData newdata;
 +    std::list<FormulaData *> formulas;
 +    bool configured;
 +
 +  protected:
 +    std::map<int, int> idmap;
 +
 +    void insert(int sim_id, int db_id)
 +    {
 +        using namespace std;
 +        idmap.insert(make_pair(sim_id, db_id));
 +    }
 +
 +    int find(int sim_id)
 +    {
 +        using namespace std;
 +        map<int,int>::const_iterator i = idmap.find(sim_id);
 +        assert(i != idmap.end());
 +        return (*i).second;
 +    }
 +  public:
 +    // Implement Visit
 +    virtual void visit(const ScalarData &data);
 +    virtual void visit(const VectorData &data);
 +    virtual void visit(const DistData &data);
 +    virtual void visit(const VectorDistData &data);
 +    virtual void visit(const Vector2dData &data);
 +    virtual void visit(const FormulaData &data);
 +
 +    // Implement Output
 +    virtual bool valid() const;
 +    virtual void output();
 +
 +  protected:
 +    // Output helper
 +    void output(const DistDataData &data);
 +    void output(const ScalarData &data);
 +    void output(const VectorData &data);
 +    void output(const DistData &data);
 +    void output(const VectorDistData &data);
 +    void output(const Vector2dData &data);
 +    void output(const FormulaData &data);
 +
 +    void configure();
 +    bool configure(const StatData &data, std::string type);
 +    void configure(const ScalarData &data);
 +    void configure(const VectorData &data);
 +    void configure(const DistData &data);
 +    void configure(const VectorDistData &data);
 +    void configure(const Vector2dData &data);
 +    void configure(const FormulaData &data);
 +};
 +
 +/* namespace Stats */ }
 +
 +#endif // __BASE_STATS_MYSQL_HH__
index 682f62dc1cb045fb80cd5d03282072d15f2dfe87,0000000000000000000000000000000000000000..f9136807adffe81a51ac7dcc218b232b6fb4e09d
mode 100644,000000..100644
--- /dev/null
@@@ -1,95 -1,0 +1,83 @@@
- #include "base/stats/bin.hh"
 +/*
 + * 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
 + * 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 "base/misc.hh"
 +#include "base/trace.hh"
 +#include "base/statistics.hh"
- void
- regBin(MainBin *bin, const std::string &_name)
- {
-     bin_list_t::iterator i, end = bins().end();
-     for (i = bins().begin(); i != end; ++i)
-         if ((*i)->name() == _name)
-             panic("re-registering bin %s", _name);
-     bins().push_back(bin);
-     DPRINTF(Stats, "registering %s\n", _name);
- }
 +#include "base/stats/statdb.hh"
 +
 +using namespace std;
 +
 +namespace Stats {
 +namespace Database {
 +
 +StatData *
 +find(void *stat)
 +{
 +    stat_map_t::const_iterator i = map().find(stat);
 +
 +    if (i == map().end())
 +        return NULL;
 +
 +    return (*i).second;
 +}
 +
 +void
 +regStat(void *stat, StatData *data)
 +{
 +    if (map().find(stat) != map().end())
 +        panic("shouldn't register stat twice!");
 +
 +    stats().push_back(data);
 +
 +#ifndef NDEBUG
 +    pair<stat_map_t::iterator, bool> result =
 +#endif
 +        map().insert(make_pair(stat, data));
 +    assert(result.second && "this should never fail");
 +    assert(map().find(stat) != map().end());
 +}
 +
 +void
 +regPrint(void *stat)
 +{
 +    StatData *data = find(stat);
 +    assert(data);
 +    data->flags |= print;
 +}
 +
 +TheDatabase &db()
 +{
 +    static TheDatabase db;
 +    return db;
 +}
 +
 +/* namespace Database */ }
 +/* namespace Stats */ }
index 8c56e031e02ab40c41c6e02f3f789a6934342c6d,0000000000000000000000000000000000000000..a5b9be7eb2ac1e4d925e2f00cfde72fe07fa101f
mode 100644,000000..100644
--- /dev/null
@@@ -1,76 -1,0 +1,70 @@@
- class MainBin;
 +/*
 + * 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
 + * 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
 + */
 +
 +#ifndef __BASE_STATS_STATDB_HH__
 +#define __BASE_STATS_STATDB_HH__
 +
 +#include <iosfwd>
 +#include <list>
 +#include <map>
 +#include <string>
 +
 +class Python;
 +
 +namespace Stats {
 +
- typedef std::list<MainBin *> bin_list_t;
 +class StatData;
 +
 +namespace Database {
 +
 +typedef std::map<void *, StatData *> stat_map_t;
 +typedef std::list<StatData *> stat_list_t;
-     bin_list_t bins;
 +
 +// We wrap the database in a struct to make sure it is built in time.
 +struct TheDatabase
 +{
 +    stat_map_t map;
 +    stat_list_t stats;
- inline bin_list_t &bins() { return db().bins; }
 +};
 +
 +TheDatabase &db();
 +inline stat_map_t &map() { return db().map; }
 +inline stat_list_t &stats() { return db().stats; }
- void regBin(MainBin *bin, const std::string &name);
 +
 +StatData *find(void *stat);
 +void regStat(void *stat, StatData *data);
 +void regPrint(void *stat);
 +
 +inline std::string name() { return "Statistics Database"; }
 +
 +/* namespace Database */ }
 +/* namespace Stats */ }
 +
 +#endif // __BASE_STATS_STATDB_HH__
index 8d21446657c3f17ce29bbdd742aba6197fa3752b,0000000000000000000000000000000000000000..c4448efc9df966155e2fad8ea2b1b964ec5311be
mode 100644,000000..100644
--- /dev/null
@@@ -1,738 -1,0 +1,724 @@@
-     if (bins().empty() || bins().size() == 1) {
-         stat_list_t::const_iterator i, end = stats().end();
-         for (i = stats().begin(); i != end; ++i)
-             (*i)->visit(*this);
-     } else {
-         ccprintf(*stream, "PRINTING BINNED STATS\n");
-         bin_list_t::iterator i, end = bins().end();
-         for (i = bins().begin(); i != end; ++i) {
-             MainBin *bin = *i;
-             bin->activate();
-             ccprintf(*stream,"---%s Bin------------\n", bin->name());
-             stat_list_t::const_iterator i, end = stats().end();
-             for (i = stats().begin(); i != end; ++i)
-                 (*i)->visit(*this);
-             ccprintf(*stream, "---------------------------------\n");
-         }
-     }
 +/*
 + * 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
 + * 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
 + */
 +
 +#if defined(__APPLE__)
 +#define _GLIBCPP_USE_C99 1
 +#endif
 +
 +#include <iostream>
 +#include <sstream>
 +#include <fstream>
 +#include <string>
 +
 +#include "base/misc.hh"
 +#include "base/statistics.hh"
 +#include "base/stats/statdb.hh"
 +#include "base/stats/text.hh"
 +#include "base/stats/visit.hh"
 +
 +using namespace std;
 +
 +#ifndef NAN
 +float __nan();
 +/** Define Not a number. */
 +#define NAN (__nan())
 +/** Need to define __nan() */
 +#define __M5_NAN
 +#endif
 +
 +#ifdef __M5_NAN
 +float
 +__nan()
 +{
 +    union {
 +        uint32_t ui;
 +        float f;
 +    } nan;
 +
 +    nan.ui = 0x7fc00000;
 +    return nan.f;
 +}
 +#endif
 +
 +namespace Stats {
 +
 +Text::Text()
 +    : mystream(false), stream(NULL), compat(false), descriptions(false)
 +{
 +}
 +
 +Text::Text(std::ostream &stream)
 +    : mystream(false), stream(NULL), compat(false), descriptions(false)
 +{
 +    open(stream);
 +}
 +
 +Text::Text(const std::string &file)
 +    : mystream(false), stream(NULL), compat(false), descriptions(false)
 +{
 +    open(file);
 +}
 +
 +
 +Text::~Text()
 +{
 +    if (mystream) {
 +        assert(stream);
 +        delete stream;
 +    }
 +}
 +
 +void
 +Text::open(std::ostream &_stream)
 +{
 +    if (stream)
 +        panic("stream already set!");
 +
 +    mystream = false;
 +    stream = &_stream;
 +    assert(valid());
 +}
 +
 +void
 +Text::open(const std::string &file)
 +{
 +    if (stream)
 +        panic("stream already set!");
 +
 +    mystream = true;
 +    stream = new ofstream(file.c_str(), ios::trunc);
 +    assert(valid());
 +}
 +
 +bool
 +Text::valid() const
 +{
 +    return stream != NULL;
 +}
 +
 +void
 +Text::output()
 +{
 +    using namespace Database;
 +
 +    ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
++    stat_list_t::const_iterator i, end = stats().end();
++    for (i = stats().begin(); i != end; ++i)
++        (*i)->visit(*this);
 +    ccprintf(*stream, "\n---------- End Simulation Statistics   ----------\n");
 +    stream->flush();
 +}
 +
 +bool
 +Text::noOutput(const StatData &data)
 +{
 +    if (!(data.flags & print))
 +        return true;
 +
 +    if (data.prereq && data.prereq->zero())
 +        return true;
 +
 +    return false;
 +}
 +
 +string
 +ValueToString(Result value, int precision, bool compat)
 +{
 +    stringstream val;
 +
 +    if (!isnan(value)) {
 +        if (precision != -1)
 +            val.precision(precision);
 +        else if (value == rint(value))
 +            val.precision(0);
 +
 +        val.unsetf(ios::showpoint);
 +        val.setf(ios::fixed);
 +        val << value;
 +    } else {
 +        val << (compat ? "<err: div-0>" : "no value");
 +    }
 +
 +    return val.str();
 +}
 +
 +struct ScalarPrint
 +{
 +    Result value;
 +    string name;
 +    string desc;
 +    StatFlags flags;
 +    bool compat;
 +    bool descriptions;
 +    int precision;
 +    Result pdf;
 +    Result cdf;
 +
 +    void operator()(ostream &stream) const;
 +};
 +
 +void
 +ScalarPrint::operator()(ostream &stream) const
 +{
 +    if (flags & nozero && value == 0.0 ||
 +        flags & nonan && isnan(value))
 +        return;
 +
 +    stringstream pdfstr, cdfstr;
 +
 +    if (!isnan(pdf))
 +        ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
 +
 +    if (!isnan(cdf))
 +        ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
 +
 +    if (compat && flags & __substat) {
 +        ccprintf(stream, "%32s %12s %10s %10s", name,
 +                 ValueToString(value, precision, compat), pdfstr, cdfstr);
 +    } else {
 +        ccprintf(stream, "%-40s %12s %10s %10s", name,
 +                 ValueToString(value, precision, compat), pdfstr, cdfstr);
 +    }
 +
 +    if (descriptions) {
 +        if (!desc.empty())
 +            ccprintf(stream, " # %s", desc);
 +    }
 +    stream << endl;
 +}
 +
 +struct VectorPrint
 +{
 +    string name;
 +    string desc;
 +    vector<string> subnames;
 +    vector<string> subdescs;
 +    StatFlags flags;
 +    bool compat;
 +    bool descriptions;
 +    int precision;
 +    VResult vec;
 +    Result total;
 +
 +    void operator()(ostream &stream) const;
 +};
 +
 +void
 +VectorPrint::operator()(std::ostream &stream) const
 +{
 +    int _size = vec.size();
 +    Result _total = 0.0;
 +
 +    if (flags & (pdf | cdf)) {
 +        for (int i = 0; i < _size; ++i) {
 +            _total += vec[i];
 +        }
 +    }
 +
 +    string base = name + (compat ? "_" : "::");
 +
 +    ScalarPrint print;
 +    print.name = name;
 +    print.desc = desc;
 +    print.precision = precision;
 +    print.descriptions = descriptions;
 +    print.flags = flags;
 +    print.pdf = NAN;
 +    print.cdf = NAN;
 +
 +    bool havesub = !subnames.empty();
 +
 +    if (_size == 1) {
 +        print.value = vec[0];
 +        print(stream);
 +    } else if (!compat) {
 +        for (int i = 0; i < _size; ++i) {
 +            if (havesub && (i >= subnames.size() || subnames[i].empty()))
 +                continue;
 +
 +            print.name = base + (havesub ? subnames[i] : to_string(i));
 +            print.desc = subdescs.empty() ? desc : subdescs[i];
 +            print.value = vec[i];
 +
 +            if (_total && (flags & pdf)) {
 +                print.pdf = vec[i] / _total;
 +                print.cdf += print.pdf;
 +            }
 +
 +            print(stream);
 +        }
 +
 +        if (flags & ::Stats::total) {
 +            print.name = base + "total";
 +            print.desc = desc;
 +            print.value = total;
 +            print(stream);
 +        }
 +    } else {
 +        if (flags & ::Stats::total) {
 +            print.value = total;
 +            print(stream);
 +        }
 +
 +        Result _pdf = 0.0;
 +        Result _cdf = 0.0;
 +        if (flags & dist) {
 +            ccprintf(stream, "%s.start_dist\n", name);
 +            for (int i = 0; i < _size; ++i) {
 +                print.name = havesub ? subnames[i] : to_string(i);
 +                print.desc = subdescs.empty() ? desc : subdescs[i];
 +                print.flags |= __substat;
 +                print.value = vec[i];
 +
 +                if (_total) {
 +                    _pdf = vec[i] / _total;
 +                    _cdf += _pdf;
 +                }
 +
 +                if (flags & pdf)
 +                    print.pdf = _pdf;
 +                if (flags & cdf)
 +                    print.cdf = _cdf;
 +
 +                print(stream);
 +            }
 +            ccprintf(stream, "%s.end_dist\n", name);
 +        } else {
 +            for (int i = 0; i < _size; ++i) {
 +                if (havesub && subnames[i].empty())
 +                    continue;
 +
 +                print.name = base;
 +                print.name += havesub ? subnames[i] : to_string(i);
 +                print.desc = subdescs.empty() ? desc : subdescs[i];
 +                print.value = vec[i];
 +
 +                if (_total) {
 +                    _pdf = vec[i] / _total;
 +                    _cdf += _pdf;
 +                } else {
 +                    _pdf = _cdf = NAN;
 +                }
 +
 +                if (flags & pdf) {
 +                    print.pdf = _pdf;
 +                    print.cdf = _cdf;
 +                }
 +
 +                print(stream);
 +            }
 +        }
 +    }
 +}
 +
 +struct DistPrint
 +{
 +    string name;
 +    string desc;
 +    StatFlags flags;
 +    bool compat;
 +    bool descriptions;
 +    int precision;
 +
 +    Result min_val;
 +    Result max_val;
 +    Result underflow;
 +    Result overflow;
 +    VResult vec;
 +    Result sum;
 +    Result squares;
 +    Result samples;
 +
 +    Counter min;
 +    Counter max;
 +    Counter bucket_size;
 +    int size;
 +    bool fancy;
 +
 +    void operator()(ostream &stream) const;
 +};
 +
 +void
 +DistPrint::operator()(ostream &stream) const
 +{
 +    if (fancy) {
 +        ScalarPrint print;
 +        string base = name + (compat ? "_" : "::");
 +
 +        print.precision = precision;
 +        print.flags = flags;
 +        print.compat = compat;
 +        print.descriptions = descriptions;
 +        print.desc = desc;
 +        print.pdf = NAN;
 +        print.cdf = NAN;
 +
 +        print.name = base + "mean";
 +        print.value = samples ? sum / samples : NAN;
 +        print(stream);
 +
 +        print.name = base + "stdev";
 +        print.value = samples ? sqrt((samples * squares - sum * sum) /
 +                                     (samples * (samples - 1.0))) : NAN;
 +        print(stream);
 +
 +        print.name = "**Ignore: " + base + "TOT";
 +        print.value = samples;
 +        print(stream);
 +        return;
 +    }
 +
 +    assert(size == vec.size());
 +
 +    Result total = 0.0;
 +
 +    total += underflow;
 +    for (int i = 0; i < size; ++i)
 +        total += vec[i];
 +    total += overflow;
 +
 +    string base = name + (compat ? "." : "::");
 +
 +    ScalarPrint print;
 +    print.desc = compat ? "" : desc;
 +    print.flags = flags;
 +    print.compat = compat;
 +    print.descriptions = descriptions;
 +    print.precision = precision;
 +    print.pdf = NAN;
 +    print.cdf = NAN;
 +
 +    if (compat) {
 +        ccprintf(stream, "%-42s", base + "start_dist");
 +        if (descriptions && !desc.empty())
 +            ccprintf(stream, "                     # %s", desc);
 +        stream << endl;
 +    }
 +
 +    print.name = base + "samples";
 +    print.value = samples;
 +    print(stream);
 +
 +    print.name = base + "min_value";
 +    print.value = min_val;
 +    print(stream);
 +
 +    if (!compat || underflow > 0.0) {
 +        print.name = base + "underflows";
 +        print.value = underflow;
 +        if (!compat && total) {
 +            print.pdf = underflow / total;
 +            print.cdf += print.pdf;
 +        }
 +        print(stream);
 +    }
 +
 +
 +    if (!compat) {
 +        for (int i = 0; i < size; ++i) {
 +            stringstream namestr;
 +            namestr << name;
 +
 +            Counter low = i * bucket_size + min;
 +            Counter high = ::min(low + bucket_size, max);
 +            namestr << low;
 +            if (low < high)
 +                namestr << "-" << high;
 +
 +            print.name = namestr.str();
 +            print.value = vec[i];
 +            if (total) {
 +                print.pdf = vec[i] / total;
 +                print.cdf += print.pdf;
 +            }
 +            print(stream);
 +        }
 +
 +    } else {
 +        Counter _min;
 +        Result _pdf;
 +        Result _cdf = 0.0;
 +
 +        print.flags = flags | __substat;
 +
 +        for (int i = 0; i < size; ++i) {
 +            if (flags & nozero && vec[i] == 0.0 ||
 +                flags & nonan && isnan(vec[i]))
 +                continue;
 +
 +            _min = i * bucket_size + min;
 +            _pdf = vec[i] / total * 100.0;
 +            _cdf += _pdf;
 +
 +
 +            print.name = ValueToString(_min, 0, compat);
 +            print.value = vec[i];
 +            print.pdf = (flags & pdf) ? _pdf : NAN;
 +            print.cdf = (flags & cdf) ? _cdf : NAN;
 +            print(stream);
 +        }
 +
 +        print.flags = flags;
 +    }
 +
 +    if (!compat || overflow > 0.0) {
 +        print.name = base + "overflows";
 +        print.value = overflow;
 +        if (!compat && total) {
 +            print.pdf = overflow / total;
 +            print.cdf += print.pdf;
 +        } else {
 +            print.pdf = NAN;
 +            print.cdf = NAN;
 +        }
 +        print(stream);
 +    }
 +
 +    print.pdf = NAN;
 +    print.cdf = NAN;
 +
 +    if (!compat) {
 +        print.name = base + "total";
 +        print.value = total;
 +        print(stream);
 +    }
 +
 +    print.name = base + "max_value";
 +    print.value = max_val;
 +    print(stream);
 +
 +    if (!compat && samples != 0) {
 +        print.name = base + "mean";
 +        print.value = sum / samples;
 +        print(stream);
 +
 +        print.name = base + "stdev";
 +        print.value = sqrt((samples * squares - sum * sum) /
 +                           (samples * (samples - 1.0)));
 +        print(stream);
 +    }
 +
 +    if (compat)
 +        ccprintf(stream, "%send_dist\n\n", base);
 +}
 +
 +void
 +Text::visit(const ScalarData &data)
 +{
 +    if (noOutput(data))
 +        return;
 +
 +    ScalarPrint print;
 +    print.value = data.result();
 +    print.name = data.name;
 +    print.desc = data.desc;
 +    print.flags = data.flags;
 +    print.compat = compat;
 +    print.descriptions = descriptions;
 +    print.precision = data.precision;
 +    print.pdf = NAN;
 +    print.cdf = NAN;
 +
 +    print(*stream);
 +}
 +
 +void
 +Text::visit(const VectorData &data)
 +{
 +    if (noOutput(data))
 +        return;
 +
 +    int size = data.size();
 +    VectorPrint print;
 +
 +    print.name = data.name;
 +    print.desc = data.desc;
 +    print.flags = data.flags;
 +    print.compat = compat;
 +    print.descriptions = descriptions;
 +    print.precision = data.precision;
 +    print.vec = data.result();
 +    print.total = data.total();
 +
 +    if (!data.subnames.empty()) {
 +        for (int i = 0; i < size; ++i) {
 +            if (!data.subnames[i].empty()) {
 +                print.subnames = data.subnames;
 +                print.subnames.resize(size);
 +                for (int i = 0; i < size; ++i) {
 +                    if (!data.subnames[i].empty() &&
 +                        !data.subdescs[i].empty()) {
 +                        print.subdescs = data.subdescs;
 +                        print.subdescs.resize(size);
 +                        break;
 +                    }
 +                }
 +                break;
 +            }
 +        }
 +    }
 +
 +    print(*stream);
 +}
 +
 +void
 +Text::visit(const Vector2dData &data)
 +{
 +    if (noOutput(data))
 +        return;
 +
 +    bool havesub = false;
 +    VectorPrint print;
 +
 +    print.subnames = data.y_subnames;
 +    print.flags = data.flags;
 +    print.compat = compat;
 +    print.descriptions = descriptions;
 +    print.precision = data.precision;
 +
 +    if (!data.subnames.empty()) {
 +        for (int i = 0; i < data.x; ++i)
 +            if (!data.subnames[i].empty())
 +                havesub = true;
 +    }
 +
 +    VResult tot_vec(data.y);
 +    Result super_total = 0.0;
 +    for (int i = 0; i < data.x; ++i) {
 +        if (havesub && (i >= data.subnames.size() || data.subnames[i].empty()))
 +            continue;
 +
 +        int iy = i * data.y;
 +        VResult yvec(data.y);
 +
 +        Result total = 0.0;
 +        for (int j = 0; j < data.y; ++j) {
 +            yvec[j] = data.cvec[iy + j];
 +            tot_vec[j] += yvec[j];
 +            total += yvec[j];
 +            super_total += yvec[j];
 +        }
 +
 +        print.name = data.name + "_" + (havesub ? data.subnames[i] : to_string(i));
 +        print.desc = data.desc;
 +        print.vec = yvec;
 +        print.total = total;
 +        print(*stream);
 +    }
 +
 +    if ((data.flags & ::Stats::total) && (data.x > 1)) {
 +        print.name = data.name;
 +        print.desc = data.desc;
 +        print.vec = tot_vec;
 +        print.total = super_total;
 +        print(*stream);
 +    }
 +}
 +
 +void
 +Text::visit(const DistData &data)
 +{
 +    if (noOutput(data))
 +        return;
 +
 +    DistPrint print;
 +
 +    print.name = data.name;
 +    print.desc = data.desc;
 +    print.flags = data.flags;
 +    print.compat = compat;
 +    print.descriptions = descriptions;
 +    print.precision = data.precision;
 +
 +    print.min_val = data.data.min_val;
 +    print.max_val = data.data.max_val;
 +    print.underflow = data.data.underflow;
 +    print.overflow = data.data.overflow;
 +    print.vec.resize(data.data.cvec.size());
 +    for (int i = 0; i < print.vec.size(); ++i)
 +        print.vec[i] = (Result)data.data.cvec[i];
 +    print.sum = data.data.sum;
 +    print.squares = data.data.squares;
 +    print.samples = data.data.samples;
 +
 +    print.min = data.data.min;
 +    print.max = data.data.max;
 +    print.bucket_size = data.data.bucket_size;
 +    print.size = data.data.size;
 +    print.fancy = data.data.fancy;
 +
 +    print(*stream);
 +}
 +
 +void
 +Text::visit(const VectorDistData &data)
 +{
 +    if (noOutput(data))
 +        return;
 +
 +    for (int i = 0; i < data.size(); ++i) {
 +        DistPrint print;
 +
 +        print.name = data.name +
 +            (data.subnames[i].empty() ? ("_" + to_string(i)) : data.subnames[i]);
 +        print.desc = data.subdescs[i].empty() ? data.desc : data.subdescs[i];
 +        print.flags = data.flags;
 +        print.compat = compat;
 +        print.descriptions = descriptions;
 +        print.precision = data.precision;
 +
 +        print.min_val = data.data[i].min_val;
 +        print.max_val = data.data[i].max_val;
 +        print.underflow = data.data[i].underflow;
 +        print.overflow = data.data[i].overflow;
 +        print.vec.resize(data.data[i].cvec.size());
 +        for (int j = 0; j < print.vec.size(); ++j)
 +            print.vec[j] = (Result)data.data[i].cvec[j];
 +        print.sum = data.data[i].sum;
 +        print.squares = data.data[i].squares;
 +        print.samples = data.data[i].samples;
 +
 +        print.min = data.data[i].min;
 +        print.max = data.data[i].max;
 +        print.bucket_size = data.data[i].bucket_size;
 +        print.size = data.data[i].size;
 +        print.fancy = data.data[i].fancy;
 +
 +        print(*stream);
 +    }
 +}
 +
 +void
 +Text::visit(const FormulaData &data)
 +{
 +    visit((const VectorData &)data);
 +}
 +
 +/* namespace Stats */ }
index de27abe1bf2b7928e62aeda20194022ac0f35671,0000000000000000000000000000000000000000..b3faf5ad533a2bff694925384399048d57482694
mode 100644,000000..100644
--- /dev/null
@@@ -1,79 -1,0 +1,78 @@@
-     void binout();
 +/*
 + * 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
 + * 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
 + */
 +
 +#ifndef __BASE_STATS_TEXT_HH__
 +#define __BASE_STATS_TEXT_HH__
 +
 +#include <iosfwd>
 +#include <string>
 +
 +#include "base/stats/output.hh"
 +
 +namespace Stats {
 +
 +class Text : public Output
 +{
 +  protected:
 +    bool mystream;
 +    std::ostream *stream;
 +
 +  protected:
 +    bool noOutput(const StatData &data);
 +
 +  public:
 +    bool compat;
 +    bool descriptions;
 +
 +  public:
 +    Text();
 +    Text(std::ostream &stream);
 +    Text(const std::string &file);
 +    ~Text();
 +
 +    void open(std::ostream &stream);
 +    void open(const std::string &file);
 +
 +    // Implement Visit
 +    virtual void visit(const ScalarData &data);
 +    virtual void visit(const VectorData &data);
 +    virtual void visit(const DistData &data);
 +    virtual void visit(const VectorDistData &data);
 +    virtual void visit(const Vector2dData &data);
 +    virtual void visit(const FormulaData &data);
 +
 +    // Implement Output
 +    virtual bool valid() const;
 +    virtual void output();
 +};
 +
 +/* namespace Stats */ }
 +
 +#endif // __BASE_STATS_TEXT_HH__
index c1ecf396764744bce32ab863a3ea780e1fb75868,0000000000000000000000000000000000000000..d94b0e079919e59bc60af5fdefe4575d950574db
mode 100644,000000..100644
--- /dev/null
@@@ -1,474 -1,0 +1,469 @@@
-     if (system->kernelBinning->fnbin) {
-         assert(thread->getKernelStats());
-         system->kernelBinning->execute(tc, inst);
-     }
 +/*
 + * 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
 + * 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
 + */
 +
 +#include "arch/utility.hh"
 +#include "base/cprintf.hh"
 +#include "base/inifile.hh"
 +#include "base/loader/symtab.hh"
 +#include "base/misc.hh"
 +#include "base/pollevent.hh"
 +#include "base/range.hh"
 +#include "base/stats/events.hh"
 +#include "base/trace.hh"
 +#include "cpu/base.hh"
 +#include "cpu/exetrace.hh"
 +#include "cpu/profile.hh"
 +#include "cpu/sampler/sampler.hh"
 +#include "cpu/simple/base.hh"
 +#include "cpu/simple_thread.hh"
 +#include "cpu/smt.hh"
 +#include "cpu/static_inst.hh"
 +#include "cpu/thread_context.hh"
 +#include "kern/kernel_stats.hh"
 +#include "mem/packet_impl.hh"
 +#include "sim/builder.hh"
 +#include "sim/byteswap.hh"
 +#include "sim/debug.hh"
 +#include "sim/host.hh"
 +#include "sim/sim_events.hh"
 +#include "sim/sim_object.hh"
 +#include "sim/stats.hh"
 +
 +#if FULL_SYSTEM
 +#include "base/remote_gdb.hh"
 +#include "sim/system.hh"
 +#include "arch/tlb.hh"
 +#include "arch/stacktrace.hh"
 +#include "arch/vtophys.hh"
 +#else // !FULL_SYSTEM
 +#include "mem/mem_object.hh"
 +#endif // FULL_SYSTEM
 +
 +using namespace std;
 +using namespace TheISA;
 +
 +BaseSimpleCPU::BaseSimpleCPU(Params *p)
 +    : BaseCPU(p), mem(p->mem), thread(NULL)
 +{
 +#if FULL_SYSTEM
 +    thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
 +#else
 +    thread = new SimpleThread(this, /* thread_num */ 0, p->process,
 +            /* asid */ 0, mem);
 +#endif // !FULL_SYSTEM
 +
 +    thread->setStatus(ThreadContext::Suspended);
 +
 +    tc = thread->getTC();
 +
 +    numInst = 0;
 +    startNumInst = 0;
 +    numLoad = 0;
 +    startNumLoad = 0;
 +    lastIcacheStall = 0;
 +    lastDcacheStall = 0;
 +
 +    threadContexts.push_back(tc);
 +}
 +
 +BaseSimpleCPU::~BaseSimpleCPU()
 +{
 +}
 +
 +void
 +BaseSimpleCPU::deallocateContext(int thread_num)
 +{
 +    // for now, these are equivalent
 +    suspendContext(thread_num);
 +}
 +
 +
 +void
 +BaseSimpleCPU::haltContext(int thread_num)
 +{
 +    // for now, these are equivalent
 +    suspendContext(thread_num);
 +}
 +
 +
 +void
 +BaseSimpleCPU::regStats()
 +{
 +    using namespace Stats;
 +
 +    BaseCPU::regStats();
 +
 +    numInsts
 +        .name(name() + ".num_insts")
 +        .desc("Number of instructions executed")
 +        ;
 +
 +    numMemRefs
 +        .name(name() + ".num_refs")
 +        .desc("Number of memory references")
 +        ;
 +
 +    notIdleFraction
 +        .name(name() + ".not_idle_fraction")
 +        .desc("Percentage of non-idle cycles")
 +        ;
 +
 +    idleFraction
 +        .name(name() + ".idle_fraction")
 +        .desc("Percentage of idle cycles")
 +        ;
 +
 +    icacheStallCycles
 +        .name(name() + ".icache_stall_cycles")
 +        .desc("ICache total stall cycles")
 +        .prereq(icacheStallCycles)
 +        ;
 +
 +    dcacheStallCycles
 +        .name(name() + ".dcache_stall_cycles")
 +        .desc("DCache total stall cycles")
 +        .prereq(dcacheStallCycles)
 +        ;
 +
 +    icacheRetryCycles
 +        .name(name() + ".icache_retry_cycles")
 +        .desc("ICache total retry cycles")
 +        .prereq(icacheRetryCycles)
 +        ;
 +
 +    dcacheRetryCycles
 +        .name(name() + ".dcache_retry_cycles")
 +        .desc("DCache total retry cycles")
 +        .prereq(dcacheRetryCycles)
 +        ;
 +
 +    idleFraction = constant(1.0) - notIdleFraction;
 +}
 +
 +void
 +BaseSimpleCPU::resetStats()
 +{
 +    startNumInst = numInst;
 +    // notIdleFraction = (_status != Idle);
 +}
 +
 +void
 +BaseSimpleCPU::serialize(ostream &os)
 +{
 +    BaseCPU::serialize(os);
 +    SERIALIZE_SCALAR(inst);
 +    nameOut(os, csprintf("%s.xc", name()));
 +    thread->serialize(os);
 +}
 +
 +void
 +BaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
 +{
 +    BaseCPU::unserialize(cp, section);
 +    UNSERIALIZE_SCALAR(inst);
 +    thread->unserialize(cp, csprintf("%s.xc", section));
 +}
 +
 +void
 +change_thread_state(int thread_number, int activate, int priority)
 +{
 +}
 +
 +Fault
 +BaseSimpleCPU::copySrcTranslate(Addr src)
 +{
 +#if 0
 +    static bool no_warn = true;
 +    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
 +    // Only support block sizes of 64 atm.
 +    assert(blk_size == 64);
 +    int offset = src & (blk_size - 1);
 +
 +    // Make sure block doesn't span page
 +    if (no_warn &&
 +        (src & PageMask) != ((src + blk_size) & PageMask) &&
 +        (src >> 40) != 0xfffffc) {
 +        warn("Copied block source spans pages %x.", src);
 +        no_warn = false;
 +    }
 +
 +    memReq->reset(src & ~(blk_size - 1), blk_size);
 +
 +    // translate to physical address
 +    Fault fault = thread->translateDataReadReq(req);
 +
 +    if (fault == NoFault) {
 +        thread->copySrcAddr = src;
 +        thread->copySrcPhysAddr = memReq->paddr + offset;
 +    } else {
 +        assert(!fault->isAlignmentFault());
 +
 +        thread->copySrcAddr = 0;
 +        thread->copySrcPhysAddr = 0;
 +    }
 +    return fault;
 +#else
 +    return NoFault;
 +#endif
 +}
 +
 +Fault
 +BaseSimpleCPU::copy(Addr dest)
 +{
 +#if 0
 +    static bool no_warn = true;
 +    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
 +    // Only support block sizes of 64 atm.
 +    assert(blk_size == 64);
 +    uint8_t data[blk_size];
 +    //assert(thread->copySrcAddr);
 +    int offset = dest & (blk_size - 1);
 +
 +    // Make sure block doesn't span page
 +    if (no_warn &&
 +        (dest & PageMask) != ((dest + blk_size) & PageMask) &&
 +        (dest >> 40) != 0xfffffc) {
 +        no_warn = false;
 +        warn("Copied block destination spans pages %x. ", dest);
 +    }
 +
 +    memReq->reset(dest & ~(blk_size -1), blk_size);
 +    // translate to physical address
 +    Fault fault = thread->translateDataWriteReq(req);
 +
 +    if (fault == NoFault) {
 +        Addr dest_addr = memReq->paddr + offset;
 +        // Need to read straight from memory since we have more than 8 bytes.
 +        memReq->paddr = thread->copySrcPhysAddr;
 +        thread->mem->read(memReq, data);
 +        memReq->paddr = dest_addr;
 +        thread->mem->write(memReq, data);
 +        if (dcacheInterface) {
 +            memReq->cmd = Copy;
 +            memReq->completionEvent = NULL;
 +            memReq->paddr = thread->copySrcPhysAddr;
 +            memReq->dest = dest_addr;
 +            memReq->size = 64;
 +            memReq->time = curTick;
 +            memReq->flags &= ~INST_READ;
 +            dcacheInterface->access(memReq);
 +        }
 +    }
 +    else
 +        assert(!fault->isAlignmentFault());
 +
 +    return fault;
 +#else
 +    panic("copy not implemented");
 +    return NoFault;
 +#endif
 +}
 +
 +#if FULL_SYSTEM
 +Addr
 +BaseSimpleCPU::dbg_vtophys(Addr addr)
 +{
 +    return vtophys(tc, addr);
 +}
 +#endif // FULL_SYSTEM
 +
 +#if FULL_SYSTEM
 +void
 +BaseSimpleCPU::post_interrupt(int int_num, int index)
 +{
 +    BaseCPU::post_interrupt(int_num, index);
 +
 +    if (thread->status() == ThreadContext::Suspended) {
 +                DPRINTF(IPI,"Suspended Processor awoke\n");
 +        thread->activate();
 +    }
 +}
 +#endif // FULL_SYSTEM
 +
 +void
 +BaseSimpleCPU::checkForInterrupts()
 +{
 +#if FULL_SYSTEM
 +    if (checkInterrupts && check_interrupts() && !thread->inPalMode()) {
 +        int ipl = 0;
 +        int summary = 0;
 +        checkInterrupts = false;
 +
 +        if (thread->readMiscReg(IPR_SIRR)) {
 +            for (int i = INTLEVEL_SOFTWARE_MIN;
 +                 i < INTLEVEL_SOFTWARE_MAX; i++) {
 +                if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
 +                    // See table 4-19 of 21164 hardware reference
 +                    ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
 +                    summary |= (ULL(1) << i);
 +                }
 +            }
 +        }
 +
 +        uint64_t interrupts = thread->cpu->intr_status();
 +        for (int i = INTLEVEL_EXTERNAL_MIN;
 +            i < INTLEVEL_EXTERNAL_MAX; i++) {
 +            if (interrupts & (ULL(1) << i)) {
 +                // See table 4-19 of 21164 hardware reference
 +                ipl = i;
 +                summary |= (ULL(1) << i);
 +            }
 +        }
 +
 +        if (thread->readMiscReg(IPR_ASTRR))
 +            panic("asynchronous traps not implemented\n");
 +
 +        if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) {
 +            thread->setMiscReg(IPR_ISR, summary);
 +            thread->setMiscReg(IPR_INTID, ipl);
 +
 +            Fault(new InterruptFault)->invoke(tc);
 +
 +            DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
 +                    thread->readMiscReg(IPR_IPLR), ipl, summary);
 +        }
 +    }
 +#endif
 +}
 +
 +
 +Fault
 +BaseSimpleCPU::setupFetchRequest(Request *req)
 +{
 +    // set up memory request for instruction fetch
 +    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(),
 +            thread->readNextPC(),thread->readNextNPC());
 +
 +    req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst),
 +                 (FULL_SYSTEM && (thread->readPC() & 1)) ? PHYSICAL : 0,
 +                 thread->readPC());
 +
 +    Fault fault = thread->translateInstReq(req);
 +
 +    return fault;
 +}
 +
 +
 +void
 +BaseSimpleCPU::preExecute()
 +{
 +    // maintain $r0 semantics
 +    thread->setIntReg(ZeroReg, 0);
 +#if THE_ISA == ALPHA_ISA
 +    thread->setFloatReg(ZeroReg, 0.0);
 +#endif // ALPHA_ISA
 +
 +    // keep an instruction count
 +    numInst++;
 +    numInsts++;
 +
 +    thread->funcExeInst++;
 +
 +    // check for instruction-count-based events
 +    comInstEventQueue[0]->serviceEvents(numInst);
 +
 +    // decode the instruction
 +    inst = gtoh(inst);
 +    curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC()));
 +
 +    traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst,
 +                                     thread->readPC());
 +
 +    DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
 +            curStaticInst->getName(), curStaticInst->getOpcode(),
 +            curStaticInst->machInst);
 +
 +#if FULL_SYSTEM
 +    thread->setInst(inst);
 +#endif // FULL_SYSTEM
 +}
 +
 +void
 +BaseSimpleCPU::postExecute()
 +{
 +#if FULL_SYSTEM
 +    if (thread->profile) {
 +        bool usermode =
 +            (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
 +        thread->profilePC = usermode ? 1 : thread->readPC();
 +        ProfileNode *node = thread->profile->consume(tc, inst);
 +        if (node)
 +            thread->profileNode = node;
 +    }
 +#endif
 +
 +    if (curStaticInst->isMemRef()) {
 +        numMemRefs++;
 +    }
 +
 +    if (curStaticInst->isLoad()) {
 +        ++numLoad;
 +        comLoadEventQueue[0]->serviceEvents(numLoad);
 +    }
 +
 +    traceFunctions(thread->readPC());
 +
 +    if (traceData) {
 +        traceData->finalize();
 +    }
 +}
 +
 +
 +void
 +BaseSimpleCPU::advancePC(Fault fault)
 +{
 +    if (fault != NoFault) {
 +#if FULL_SYSTEM
 +        fault->invoke(tc);
 +#else // !FULL_SYSTEM
 +        fatal("fault (%s) detected @ PC %08p", fault->name(), thread->readPC());
 +#endif // FULL_SYSTEM
 +    }
 +    else {
 +        // go to the next instruction
 +        thread->setPC(thread->readNextPC());
 +#if THE_ISA == ALPHA_ISA
 +        thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
 +#else
 +        thread->setNextPC(thread->readNextNPC());
 +        thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
 +#endif
 +
 +    }
 +
 +#if FULL_SYSTEM
 +    Addr oldpc;
 +    do {
 +        oldpc = thread->readPC();
 +        system->pcEventQueue.service(tc);
 +    } while (oldpc != thread->readPC());
 +#endif
 +}
 +
index 2ba120b6f02d580ca8ccd36eef10baeae32eb07f,0000000000000000000000000000000000000000..f7868b50f7f6bfb473ab701edcacedc541397210
mode 100644,000000..100644
--- /dev/null
@@@ -1,302 -1,0 +1,290 @@@
- const char *modestr[] = { "kernel", "user", "idle", "interrupt" };
 +/*
 + * 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
 + * 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: Lisa Hsu
 + *          Nathan Binkert
 + */
 +
 +#include <map>
 +#include <stack>
 +#include <string>
 +
 +#include "arch/alpha/osfpal.hh"
 +#include "base/trace.hh"
 +#include "cpu/thread_context.hh"
 +#include "kern/kernel_stats.hh"
 +#include "kern/tru64/tru64_syscalls.hh"
 +#include "sim/system.hh"
 +
 +using namespace std;
 +using namespace Stats;
 +
 +namespace Kernel {
 +
-     bin_int = system->params()->bin_int;
++const char *modestr[] = { "kernel", "user", "idle" };
 +
 +Statistics::Statistics(System *system)
 +    : idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
 +      iplLast(0), iplLastTick(0)
 +{
-     assert(themode == kernel || themode == interrupt);
 +}
 +
 +void
 +Statistics::regStats(const string &_name)
 +{
 +    myname = _name;
 +
 +    _arm
 +        .name(name() + ".inst.arm")
 +        .desc("number of arm instructions executed")
 +        ;
 +
 +    _quiesce
 +        .name(name() + ".inst.quiesce")
 +        .desc("number of quiesce instructions executed")
 +        ;
 +
 +    _ivlb
 +        .name(name() + ".inst.ivlb")
 +        .desc("number of ivlb instructions executed")
 +        ;
 +
 +    _ivle
 +        .name(name() + ".inst.ivle")
 +        .desc("number of ivle instructions executed")
 +        ;
 +
 +    _hwrei
 +        .name(name() + ".inst.hwrei")
 +        .desc("number of hwrei instructions executed")
 +        ;
 +
 +    _iplCount
 +        .init(32)
 +        .name(name() + ".ipl_count")
 +        .desc("number of times we switched to this ipl")
 +        .flags(total | pdf | nozero | nonan)
 +        ;
 +
 +    _iplGood
 +        .init(32)
 +        .name(name() + ".ipl_good")
 +        .desc("number of times we switched to this ipl from a different ipl")
 +        .flags(total | pdf | nozero | nonan)
 +        ;
 +
 +    _iplTicks
 +        .init(32)
 +        .name(name() + ".ipl_ticks")
 +        .desc("number of cycles we spent at this ipl")
 +        .flags(total | pdf | nozero | nonan)
 +        ;
 +
 +    _iplUsed
 +        .name(name() + ".ipl_used")
 +        .desc("fraction of swpipl calls that actually changed the ipl")
 +        .flags(total | nozero | nonan)
 +        ;
 +
 +    _iplUsed = _iplGood / _iplCount;
 +
 +    _callpal
 +        .init(256)
 +        .name(name() + ".callpal")
 +        .desc("number of callpals executed")
 +        .flags(total | pdf | nozero | nonan)
 +        ;
 +
 +    for (int i = 0; i < PAL::NumCodes; ++i) {
 +        const char *str = PAL::name(i);
 +        if (str)
 +            _callpal.subname(i, str);
 +    }
 +
 +    _syscall
 +        .init(SystemCalls<Tru64>::Number)
 +        .name(name() + ".syscall")
 +        .desc("number of syscalls executed")
 +        .flags(total | pdf | nozero | nonan)
 +        ;
 +
 +    for (int i = 0; i < SystemCalls<Tru64>::Number; ++i) {
 +        const char *str = SystemCalls<Tru64>::name(i);
 +        if (str) {
 +            _syscall.subname(i, str);
 +        }
 +    }
 +
 +    _mode
 +        .init(cpu_mode_num)
 +        .name(name() + ".mode_switch")
 +        .desc("number of protection mode switches")
 +        ;
 +
 +    for (int i = 0; i < cpu_mode_num; ++i)
 +        _mode.subname(i, modestr[i]);
 +
 +    _modeGood
 +        .init(cpu_mode_num)
 +        .name(name() + ".mode_good")
 +        ;
 +
 +    for (int i = 0; i < cpu_mode_num; ++i)
 +        _modeGood.subname(i, modestr[i]);
 +
 +    _modeFraction
 +        .name(name() + ".mode_switch_good")
 +        .desc("fraction of useful protection mode switches")
 +        .flags(total)
 +        ;
 +
 +    for (int i = 0; i < cpu_mode_num; ++i)
 +        _modeFraction.subname(i, modestr[i]);
 +
 +    _modeFraction = _modeGood / _mode;
 +
 +    _modeTicks
 +        .init(cpu_mode_num)
 +        .name(name() + ".mode_ticks")
 +        .desc("number of ticks spent at the given mode")
 +        .flags(pdf)
 +        ;
 +    for (int i = 0; i < cpu_mode_num; ++i)
 +        _modeTicks.subname(i, modestr[i]);
 +
 +    _swap_context
 +        .name(name() + ".swap_context")
 +        .desc("number of times the context was actually changed")
 +        ;
 +}
 +
 +void
 +Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc)
 +{
-     tc->getSystemPtr()->kernelBinning->changeMode(newmode);
++    assert(themode == kernel);
 +    idleProcess = idlepcbb;
 +    themode = idle;
 +    changeMode(themode, tc);
 +}
 +
 +void
 +Statistics::changeMode(cpu_mode newmode, ThreadContext *tc)
 +{
 +    _mode[newmode]++;
 +
 +    if (newmode == themode)
 +        return;
 +
 +    DPRINTF(Context, "old mode=%-8s new mode=%-8s\n",
 +            modestr[themode], modestr[newmode]);
 +
 +    _modeGood[newmode]++;
 +    _modeTicks[themode] += curTick - lastModeTick;
 +
-     if ((newmode == kernel || newmode == interrupt) &&
-             pcbb == idleProcess)
 +    lastModeTick = curTick;
 +    themode = newmode;
 +}
 +
 +void
 +Statistics::swpipl(int ipl)
 +{
 +    assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n");
 +
 +    _iplCount[ipl]++;
 +
 +    if (ipl == iplLast)
 +        return;
 +
 +    _iplGood[ipl]++;
 +    _iplTicks[iplLast] += curTick - iplLastTick;
 +    iplLastTick = curTick;
 +    iplLast = ipl;
 +}
 +
 +void
 +Statistics::mode(cpu_mode newmode, ThreadContext *tc)
 +{
 +    Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23);
 +
-     if (bin_int == false && newmode == interrupt)
-         newmode = kernel;
++    if (newmode == kernel && pcbb == idleProcess)
 +        newmode = idle;
 +
-       case PAL::swpctx:
-         if (tc->getSystemPtr()->kernelBinning)
-             tc->getSystemPtr()->kernelBinning->palSwapContext(tc);
-         break;
 +    changeMode(newmode, tc);
 +}
 +
 +void
 +Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc)
 +{
 +    assert(themode != user);
 +
 +    _swap_context++;
 +    changeMode(newpcbb == idleProcess ? idle : kernel, tc);
 +}
 +
 +void
 +Statistics::callpal(int code, ThreadContext *tc)
 +{
 +    if (!PAL::name(code))
 +        return;
 +
 +    _callpal[code]++;
 +
 +    switch (code) {
 +      case PAL::callsys: {
 +          int number = tc->readIntReg(0);
 +          if (SystemCalls<Tru64>::validSyscallNumber(number)) {
 +              int cvtnum = SystemCalls<Tru64>::convert(number);
 +              _syscall[cvtnum]++;
 +          }
 +      } break;
 +    }
 +}
 +
 +void
 +Statistics::serialize(ostream &os)
 +{
 +    int exemode = themode;
 +    SERIALIZE_SCALAR(exemode);
 +    SERIALIZE_SCALAR(idleProcess);
 +    SERIALIZE_SCALAR(iplLast);
 +    SERIALIZE_SCALAR(iplLastTick);
 +    SERIALIZE_SCALAR(lastModeTick);
 +}
 +
 +void
 +Statistics::unserialize(Checkpoint *cp, const string &section)
 +{
 +    int exemode;
 +    UNSERIALIZE_SCALAR(exemode);
 +    UNSERIALIZE_SCALAR(idleProcess);
 +    UNSERIALIZE_SCALAR(iplLast);
 +    UNSERIALIZE_SCALAR(iplLastTick);
 +    UNSERIALIZE_SCALAR(lastModeTick);
 +    themode = (cpu_mode)exemode;
 +}
 +
 +/* end namespace Kernel */ }
index 781b6f6da1eeca94e60b2ac97b484201d365940c,0000000000000000000000000000000000000000..c691ad8cf16a0c30ea3f0fb3d088e741131498ed
mode 100644,000000..100644
--- /dev/null
@@@ -1,195 -1,0 +1,117 @@@
- enum cpu_mode { kernel, user, idle, interrupt, cpu_mode_num };
 +/*
 + * 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
 + * 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: Lisa Hsu
 + *          Nathan Binkert
 + */
 +
 +#ifndef __KERNEL_STATS_HH__
 +#define __KERNEL_STATS_HH__
 +
 +#include <map>
 +#include <stack>
 +#include <string>
 +#include <vector>
 +
 +#include "cpu/static_inst.hh"
 +
 +class BaseCPU;
 +class ThreadContext;
 +class FnEvent;
 +// What does kernel stats expect is included?
 +class System;
 +
 +namespace Kernel {
 +
- class Binning
- {
-   private:
-     std::string myname;
-     System *system;
-   private:
-     // lisa's binning stuff
-     struct fnCall
-     {
-         Stats::MainBin *myBin;
-         std::string name;
-     };
-     struct SWContext
-     {
-         Counter calls;
-         std::stack<fnCall *> callStack;
-     };
-     std::map<const std::string, Stats::MainBin *> fnBins;
-     std::map<const Addr, SWContext *> swCtxMap;
-     std::multimap<const std::string, std::string> callerMap;
-     void populateMap(std::string caller, std::string callee);
-     std::vector<FnEvent *> fnEvents;
-     Stats::Scalar<> fnCalls;
-     Stats::MainBin *getBin(const std::string &name);
-     bool findCaller(std::string, std::string) const;
-     SWContext *findContext(Addr pcb);
-     bool addContext(Addr pcb, SWContext *ctx)
-     {
-         return (swCtxMap.insert(std::make_pair(pcb, ctx))).second;
-     }
-     void remContext(Addr pcb)
-     {
-         swCtxMap.erase(pcb);
-     }
-     void dumpState() const;
-     SWContext *swctx;
-     std::vector<std::string> binned_fns;
-   private:
-     Stats::MainBin *modeBin[cpu_mode_num];
-   public:
-     const bool bin;
-     const bool fnbin;
-     cpu_mode themode;
-     void palSwapContext(ThreadContext *tc);
-     void execute(ThreadContext *tc, StaticInstPtr inst);
-     void call(ThreadContext *tc, Stats::MainBin *myBin);
-     void changeMode(cpu_mode mode);
-   public:
-     Binning(System *sys);
-     virtual ~Binning();
-     const std::string name() const { return myname; }
-     void regStats(const std::string &name);
-   public:
-     virtual void serialize(std::ostream &os);
-     virtual void unserialize(Checkpoint *cp, const std::string &section);
- };
++enum cpu_mode { kernel, user, idle, cpu_mode_num };
 +extern const char *modestr[];
 +
-   private:
-     friend class Binning;
 +class Statistics : public Serializable
 +{
-     bool bin_int;
 +  private:
 +    std::string myname;
 +
 +    Addr idleProcess;
 +    cpu_mode themode;
 +    Tick lastModeTick;
 +
 +    void changeMode(cpu_mode newmode, ThreadContext *tc);
 +
 +  private:
 +    Stats::Scalar<> _arm;
 +    Stats::Scalar<> _quiesce;
 +    Stats::Scalar<> _ivlb;
 +    Stats::Scalar<> _ivle;
 +    Stats::Scalar<> _hwrei;
 +
 +    Stats::Vector<> _iplCount;
 +    Stats::Vector<> _iplGood;
 +    Stats::Vector<> _iplTicks;
 +    Stats::Formula _iplUsed;
 +
 +    Stats::Vector<> _callpal;
 +    Stats::Vector<> _syscall;
 +//    Stats::Vector<> _faults;
 +
 +    Stats::Vector<> _mode;
 +    Stats::Vector<> _modeGood;
 +    Stats::Formula _modeFraction;
 +    Stats::Vector<> _modeTicks;
 +
 +    Stats::Scalar<> _swap_context;
 +
 +  private:
 +    int iplLast;
 +    Tick iplLastTick;
 +
 +  public:
 +    Statistics(System *system);
 +
 +    const std::string name() const { return myname; }
 +    void regStats(const std::string &name);
 +
 +  public:
 +    void arm() { _arm++; }
 +    void quiesce() { _quiesce++; }
 +    void ivlb() { _ivlb++; }
 +    void ivle() { _ivle++; }
 +    void hwrei() { _hwrei++; }
 +    void swpipl(int ipl);
 +    void mode(cpu_mode newmode, ThreadContext *tc);
 +    void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc);
 +    void callpal(int code, ThreadContext *tc);
 +
 +    void setIdleProcess(Addr idle, ThreadContext *tc);
 +
 +  public:
 +    virtual void serialize(std::ostream &os);
 +    virtual void unserialize(Checkpoint *cp, const std::string &section);
 +};
 +
 +/* end namespace Kernel */ }
 +
 +#endif // __KERNEL_STATS_HH__
index fe3805ce26f27874af2ecf01dcb38a5ad390c00f,0000000000000000000000000000000000000000..177ce96d16db466d197f84bda2677a4412e44260
mode 100644,000000..100644
--- /dev/null
@@@ -1,97 -1,0 +1,65 @@@
- FnEvent::FnEvent(PCEventQueue *q, const std::string &desc, Addr addr,
-                  Stats::MainBin *bin)
-     : PCEvent(q, desc, addr), _name(desc), mybin(bin)
- {
- }
- void
- FnEvent::process(ThreadContext *tc)
- {
-     if (tc->misspeculating())
-         return;
-     tc->getSystemPtr()->kernelBinning->call(tc, mybin);
- }
 +/*
 + * 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
 + * 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: Lisa Hsu
 + *          Nathan Binkert
 + */
 +
 +#include "cpu/base.hh"
 +#include "cpu/thread_context.hh"
 +#include "kern/kernel_stats.hh"
 +#include "kern/system_events.hh"
 +#include "sim/system.hh"
 +
 +using namespace TheISA;
 +
 +void
 +SkipFuncEvent::process(ThreadContext *tc)
 +{
 +    Addr newpc = tc->readIntReg(ReturnAddressReg);
 +
 +    DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description,
 +            tc->readPC(), newpc);
 +
 +    tc->setPC(newpc);
 +    tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst));
 +/*
 +    BranchPred *bp = tc->getCpuPtr()->getBranchPred();
 +    if (bp != NULL) {
 +        bp->popRAS(tc->getThreadNum());
 +    }
 +*/
 +}
 +
- void
- InterruptStartEvent::process(ThreadContext *tc)
- {
-     if (tc->getKernelStats())
-         tc->getKernelStats()->mode(Kernel::interrupt, tc);
- }
- void
- InterruptEndEvent::process(ThreadContext *tc)
- {
-     // We go back to kernel, if we are user, inside the rti
-     // pal code we will get switched to user because of the ICM write
-     if (tc->getKernelStats())
-         tc->getKernelStats()->mode(Kernel::kernel, tc);
- }
 +void
 +IdleStartEvent::process(ThreadContext *tc)
 +{
 +    if (tc->getKernelStats())
 +        tc->getKernelStats()->setIdleProcess(
 +            tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc);
 +    remove();
 +}
index 05c87857758e27408a6264f12c50b0b06bab2aba,0000000000000000000000000000000000000000..ccd6bd9a4ec11030c3cd00ef20223d2e226e6eab
mode 100644,000000..100644
--- /dev/null
@@@ -1,89 -1,0 +1,57 @@@
- class FnEvent : public PCEvent
- {
-   public:
-     FnEvent(PCEventQueue *q, const std::string &desc, Addr addr,
-             Stats::MainBin *bin);
-     virtual void process(ThreadContext *tc);
-     std::string myname() const { return _name; }
-   private:
-     std::string _name;
-     Stats::MainBin *mybin;
- };
 +/*
 + * 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
 + * 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: Lisa Hsu
 + *          Ali Saidi
 + */
 +
 +#ifndef __SYSTEM_EVENTS_HH__
 +#define __SYSTEM_EVENTS_HH__
 +
 +#include "cpu/pc_event.hh"
 +
 +class System;
 +
 +class SkipFuncEvent : public PCEvent
 +{
 +  public:
 +    SkipFuncEvent(PCEventQueue *q, const std::string &desc, Addr addr)
 +        : PCEvent(q, desc, addr)
 +    {}
 +    virtual void process(ThreadContext *tc);
 +};
 +
- class InterruptStartEvent : public PCEvent
- {
-   public:
-     InterruptStartEvent(PCEventQueue *q, const std::string &desc, Addr addr)
-         : PCEvent(q, desc, addr)
-     {}
-     virtual void process(ThreadContext *tc);
- };
- class InterruptEndEvent : public PCEvent
- {
-   public:
-     InterruptEndEvent(PCEventQueue *q, const std::string &desc, Addr addr)
-         : PCEvent(q, desc, addr)
-     {}
-     virtual void process(ThreadContext *tc);
- };
 +class IdleStartEvent : public PCEvent
 +{
 +  public:
 +    IdleStartEvent(PCEventQueue *q, const std::string &desc, Addr addr)
 +        : PCEvent(q, desc, addr)
 +    {}
 +    virtual void process(ThreadContext *tc);
 +};
 +
 +#endif // __SYSTEM_EVENTS_HH__
index a8063a274f4241269d8d5f92a371fa0b1da7aaff,0000000000000000000000000000000000000000..9a1e1d690b2c497bf3f7ccea31c2080f494d23e2
mode 100644,000000..100644
--- /dev/null
@@@ -1,22 -1,0 +1,20 @@@
-         bin = Param.Bool(False, "is this system binned")
-         binned_fns = VectorParam.String([], "functions broken down and binned")
 +from m5 import build_env
 +from m5.config import *
 +
 +class System(SimObject):
 +    type = 'System'
 +    physmem = Param.PhysicalMemory(Parent.any, "phsyical memory")
 +    if build_env['FULL_SYSTEM']:
 +        boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency,
 +                                             "boot processor frequency")
 +        init_param = Param.UInt64(0, "numerical value to pass into simulator")
 +        boot_osflags = Param.String("a", "boot flags to pass to the kernel")
 +        kernel = Param.String("file that contains the kernel code")
 +        readfile = Param.String("", "file to read startup script from")
 +
 +class AlphaSystem(System):
 +    type = 'AlphaSystem'
 +    console = Param.String("file that contains the console code")
 +    pal = Param.String("file that contains palcode")
 +    system_type = Param.UInt64("Type of system we are emulating")
 +    system_rev = Param.UInt64("Revision of system we are emulating")
index 7953607d56365a36159ac62860927699164e74b2,0000000000000000000000000000000000000000..b3c7870fddc2baab730bddcc1ab9747a455efb83
mode 100644,000000..100644
--- /dev/null
@@@ -1,300 -1,0 +1,286 @@@
-     delete kernelBinning;
 +/*
 + * Copyright (c) 2003-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
 + *          Lisa Hsu
 + *          Nathan Binkert
 + *          Ali Saidi
 + */
 +
 +#include "arch/isa_traits.hh"
 +#include "base/loader/object_file.hh"
 +#include "base/loader/symtab.hh"
 +#include "base/trace.hh"
 +#include "cpu/thread_context.hh"
 +#include "mem/mem_object.hh"
 +#include "mem/physical.hh"
 +#include "sim/builder.hh"
 +#include "sim/byteswap.hh"
 +#include "sim/system.hh"
 +#if FULL_SYSTEM
 +#include "arch/vtophys.hh"
 +#include "base/remote_gdb.hh"
 +#include "kern/kernel_stats.hh"
 +#endif
 +
 +using namespace std;
 +using namespace TheISA;
 +
 +vector<System *> System::systemList;
 +
 +int System::numSystemsRunning = 0;
 +
 +System::System(Params *p)
 +    : SimObject(p->name), physmem(p->physmem), numcpus(0),
 +#if FULL_SYSTEM
 +      init_param(p->init_param),
 +      functionalPort(p->name + "-fport"),
 +      virtPort(p->name + "-vport"),
 +#else
 +      page_ptr(0),
 +#endif
 +      _params(p)
 +{
 +    // add self to global system list
 +    systemList.push_back(this);
 +
 +#if FULL_SYSTEM
 +    kernelSymtab = new SymbolTable;
 +    debugSymbolTable = new SymbolTable;
 +
 +
 +    /**
 +     * Get a functional port to memory
 +     */
 +    Port *mem_port;
 +    mem_port = physmem->getPort("functional");
 +    functionalPort.setPeer(mem_port);
 +    mem_port->setPeer(&functionalPort);
 +
 +    mem_port = physmem->getPort("functional");
 +    virtPort.setPeer(mem_port);
 +    mem_port->setPeer(&virtPort);
 +
 +
 +    /**
 +     * Load the kernel code into memory
 +     */
 +    // Load kernel code
 +    kernel = createObjectFile(params()->kernel_path);
 +    if (kernel == NULL)
 +        fatal("Could not load kernel file %s", params()->kernel_path);
 +
 +    // Load program sections into memory
 +    kernel->loadSections(&functionalPort, LoadAddrMask);
 +
 +    // setup entry points
 +    kernelStart = kernel->textBase();
 +    kernelEnd = kernel->bssBase() + kernel->bssSize();
 +    kernelEntry = kernel->entryPoint();
 +
 +    // load symbols
 +    if (!kernel->loadGlobalSymbols(kernelSymtab))
 +        panic("could not load kernel symbols\n");
 +
 +    if (!kernel->loadLocalSymbols(kernelSymtab))
 +        panic("could not load kernel local symbols\n");
 +
 +    if (!kernel->loadGlobalSymbols(debugSymbolTable))
 +        panic("could not load kernel symbols\n");
 +
 +    if (!kernel->loadLocalSymbols(debugSymbolTable))
 +        panic("could not load kernel local symbols\n");
 +
 +    DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
 +    DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
 +    DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
 +    DPRINTF(Loader, "Kernel loaded...\n");
 +
 +    kernelBinning = new Kernel::Binning(this);
 +#endif // FULL_SYSTEM
 +
 +    // increment the number of running systms
 +    numSystemsRunning++;
 +}
 +
 +System::~System()
 +{
 +#if FULL_SYSTEM
 +    delete kernelSymtab;
 +    delete kernel;
- void
- System::regStats()
- {
- #if FULL_SYSTEM
-     kernelBinning->regStats(name() + ".kern");
- #endif // FULL_SYSTEM
- }
 +#else
 +    panic("System::fixFuncEventAddr needs to be rewritten "
 +          "to work with syscall emulation");
 +#endif // FULL_SYSTEM}
 +}
 +
 +#if FULL_SYSTEM
 +
 +
 +int rgdb_wait = -1;
 +
 +#endif // FULL_SYSTEM
 +
 +int
 +System::registerThreadContext(ThreadContext *tc, int id)
 +{
 +    if (id == -1) {
 +        for (id = 0; id < threadContexts.size(); id++) {
 +            if (!threadContexts[id])
 +                break;
 +        }
 +    }
 +
 +    if (threadContexts.size() <= id)
 +        threadContexts.resize(id + 1);
 +
 +    if (threadContexts[id])
 +        panic("Cannot have two CPUs with the same id (%d)\n", id);
 +
 +    threadContexts[id] = tc;
 +    numcpus++;
 +
 +#if FULL_SYSTEM
 +    RemoteGDB *rgdb = new RemoteGDB(this, tc);
 +    GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
 +    gdbl->listen();
 +    /**
 +     * Uncommenting this line waits for a remote debugger to connect
 +     * to the simulator before continuing.
 +     */
 +    if (rgdb_wait != -1 && rgdb_wait == id)
 +        gdbl->accept();
 +
 +    if (remoteGDB.size() <= id) {
 +        remoteGDB.resize(id + 1);
 +    }
 +
 +    remoteGDB[id] = rgdb;
 +#endif // FULL_SYSTEM
 +
 +    return id;
 +}
 +
 +void
 +System::startup()
 +{
 +    int i;
 +    for (i = 0; i < threadContexts.size(); i++)
 +        threadContexts[i]->activate(0);
 +}
 +
 +void
 +System::replaceThreadContext(ThreadContext *tc, int id)
 +{
 +    if (id >= threadContexts.size()) {
 +        panic("replaceThreadContext: bad id, %d >= %d\n",
 +              id, threadContexts.size());
 +    }
 +
 +    threadContexts[id] = tc;
 +#if FULL_SYSTEM
 +    remoteGDB[id]->replaceThreadContext(tc);
 +#endif // FULL_SYSTEM
 +}
 +
 +#if !FULL_SYSTEM
 +Addr
 +System::new_page()
 +{
 +    Addr return_addr = page_ptr << LogVMPageSize;
 +    ++page_ptr;
 +    return return_addr;
 +}
 +#endif
 +
-     kernelBinning->serialize(os);
 +void
 +System::serialize(ostream &os)
 +{
 +#if FULL_SYSTEM
-     kernelBinning->unserialize(cp, section);
 +    kernelSymtab->serialize("kernel_symtab", os);
 +#endif // FULL_SYSTEM
 +}
 +
 +
 +void
 +System::unserialize(Checkpoint *cp, const string &section)
 +{
 +#if FULL_SYSTEM
 +    kernelSymtab->unserialize("kernel_symtab", cp, section);
 +#endif // FULL_SYSTEM
 +}
 +
 +void
 +System::printSystems()
 +{
 +    vector<System *>::iterator i = systemList.begin();
 +    vector<System *>::iterator end = systemList.end();
 +    for (; i != end; ++i) {
 +        System *sys = *i;
 +        cerr << "System " << sys->name() << ": " << hex << sys << endl;
 +    }
 +}
 +
 +extern "C"
 +void
 +printSystems()
 +{
 +    System::printSystems();
 +}
 +
 +#if FULL_SYSTEM
 +
 +// In full system mode, only derived classes (e.g. AlphaLinuxSystem)
 +// can be created directly.
 +
 +DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
 +
 +#else
 +
 +BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
 +
 +    SimObjectParam<PhysicalMemory *> physmem;
 +
 +END_DECLARE_SIM_OBJECT_PARAMS(System)
 +
 +BEGIN_INIT_SIM_OBJECT_PARAMS(System)
 +
 +    INIT_PARAM(physmem, "physical memory")
 +
 +END_INIT_SIM_OBJECT_PARAMS(System)
 +
 +CREATE_SIM_OBJECT(System)
 +{
 +    System::Params *p = new System::Params;
 +    p->name = getInstanceName();
 +    p->physmem = physmem;
 +    return new System(p);
 +}
 +
 +REGISTER_SIM_OBJECT("System", System)
 +
 +#endif
index 3a9fdc3d2ba365b69fddadd7c6facc97062844e3,0000000000000000000000000000000000000000..059dc92dc7587f8314908e5ea253b1b8cdba6231
mode 100644,000000..100644
--- /dev/null
@@@ -1,233 -1,0 +1,226 @@@
- namespace Kernel { class Binning; }
 +/*
 + * 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
 + * 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
 + *          Lisa Hsu
 + *          Nathan Binkert
 + */
 +
 +#ifndef __SYSTEM_HH__
 +#define __SYSTEM_HH__
 +
 +#include <string>
 +#include <vector>
 +
 +#include "base/loader/symtab.hh"
 +#include "base/misc.hh"
 +#include "base/statistics.hh"
 +#include "cpu/pc_event.hh"
 +#include "mem/port.hh"
 +#include "sim/sim_object.hh"
 +#if FULL_SYSTEM
 +#include "kern/system_events.hh"
 +#include "mem/vport.hh"
 +#endif
 +
 +class BaseCPU;
 +class ThreadContext;
 +class ObjectFile;
 +class PhysicalMemory;
 +
 +#if FULL_SYSTEM
 +class Platform;
 +class GDBListener;
 +class RemoteGDB;
-     Kernel::Binning *kernelBinning;
 +#endif
 +
 +class System : public SimObject
 +{
 +  public:
 +    PhysicalMemory *physmem;
 +    PCEventQueue pcEventQueue;
 +
 +    std::vector<ThreadContext *> threadContexts;
 +    int numcpus;
 +
 +    int getNumCPUs()
 +    {
 +        if (numcpus != threadContexts.size())
 +            panic("cpu array not fully populated!");
 +
 +        return numcpus;
 +    }
 +
 +#if FULL_SYSTEM
 +    Platform *platform;
 +    uint64_t init_param;
 +
 +    /** Port to physical memory used for writing object files into ram at
 +     * boot.*/
 +    FunctionalPort functionalPort;
 +    VirtualPort virtPort;
 +
 +    /** kernel symbol table */
 +    SymbolTable *kernelSymtab;
 +
 +    /** Object pointer for the kernel code */
 +    ObjectFile *kernel;
 +
 +    /** Begining of kernel code */
 +    Addr kernelStart;
 +
 +    /** End of kernel code */
 +    Addr kernelEnd;
 +
 +    /** Entry point in the kernel to start at */
 +    Addr kernelEntry;
 +
-         bool bin;
-         std::vector<std::string> binned_fns;
-         bool bin_int;
 +#else
 +
 +    int page_ptr;
 +
 +
 +#endif // FULL_SYSTEM
 +
 +  protected:
 +
 +#if FULL_SYSTEM
 +    /**
 +     * Fix up an address used to match PCs for hooking simulator
 +     * events on to target function executions.  See comment in
 +     * system.cc for details.
 +     */
 +    virtual Addr fixFuncEventAddr(Addr addr) = 0;
 +
 +    /**
 +     * Add a function-based event to the given function, to be looked
 +     * up in the specified symbol table.
 +     */
 +    template <class T>
 +    T *System::addFuncEvent(SymbolTable *symtab, const char *lbl)
 +    {
 +        Addr addr = 0; // initialize only to avoid compiler warning
 +
 +        if (symtab->findAddress(lbl, addr)) {
 +            T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr));
 +            return ev;
 +        }
 +
 +        return NULL;
 +    }
 +
 +    /** Add a function-based event to kernel code. */
 +    template <class T>
 +    T *System::addKernelFuncEvent(const char *lbl)
 +    {
 +        return addFuncEvent<T>(kernelSymtab, lbl);
 +    }
 +
 +#endif
 +  public:
 +#if FULL_SYSTEM
 +    std::vector<RemoteGDB *> remoteGDB;
 +    std::vector<GDBListener *> gdbListen;
 +    virtual bool breakpoint() = 0;
 +#endif // FULL_SYSTEM
 +
 +  public:
 +    struct Params
 +    {
 +        std::string name;
 +        PhysicalMemory *physmem;
 +
 +#if FULL_SYSTEM
 +        Tick boot_cpu_frequency;
 +        std::string boot_osflags;
 +        uint64_t init_param;
-     void regStats();
 +
 +        std::string kernel_path;
 +        std::string readfile;
 +#endif
 +    };
 +
 +  protected:
 +    Params *_params;
 +
 +  public:
 +    System(Params *p);
 +    ~System();
 +
 +    void startup();
 +
 +    const Params *params() const { return (const Params *)_params; }
 +
 +  public:
 +
 +#if FULL_SYSTEM
 +    /**
 +     * Returns the addess the kernel starts at.
 +     * @return address the kernel starts at
 +     */
 +    Addr getKernelStart() const { return kernelStart; }
 +
 +    /**
 +     * Returns the addess the kernel ends at.
 +     * @return address the kernel ends at
 +     */
 +    Addr getKernelEnd() const { return kernelEnd; }
 +
 +    /**
 +     * Returns the addess the entry point to the kernel code.
 +     * @return entry point of the kernel code
 +     */
 +    Addr getKernelEntry() const { return kernelEntry; }
 +
 +#else
 +
 +    Addr new_page();
 +
 +#endif // FULL_SYSTEM
 +
 +    int registerThreadContext(ThreadContext *tc, int tcIndex);
 +    void replaceThreadContext(ThreadContext *tc, int tcIndex);
 +
 +    void serialize(std::ostream &os);
 +    void unserialize(Checkpoint *cp, const std::string &section);
 +
 +  public:
 +    ////////////////////////////////////////////
 +    //
 +    // STATIC GLOBAL SYSTEM LIST
 +    //
 +    ////////////////////////////////////////////
 +
 +    static std::vector<System *> systemList;
 +    static int numSystemsRunning;
 +
 +    static void printSystems();
 +
 +
 +};
 +
 +#endif // __SYSTEM_HH__
index 496d1f672bcf3374b9ad4ede102808a458f4ea61,0000000000000000000000000000000000000000..4e504fde985aba24395f8b1d61dc82ca57fdac63
mode 100644,000000..100644
--- /dev/null
@@@ -1,562 -1,0 +1,556 @@@
- Scalar<MainBin> s4;
- Vector<MainBin> s5;
- Distribution<MainBin> s6;
- Vector<MainBin> s7;
 +/*
 + * Copyright (c) 2003-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 <iomanip>
 +#include <iostream>
 +#include <fstream>
 +#include <string>
 +#include <unistd.h>
 +
 +#include "base/cprintf.hh"
 +#include "base/misc.hh"
 +#include "base/statistics.hh"
 +#include "base/stats/text.hh"
 +#include "base/stats/mysql.hh"
 +#include "sim/host.hh"
 +
 +using namespace std;
 +using namespace Stats;
 +
 +Tick curTick = 0;
 +Tick ticksPerSecond = ULL(2000000000);
 +
 +Scalar<> s1;
 +Scalar<> s2;
 +Average<> s3;
- MainBin bin1("bin1");
- MainBin bin2("bin2");
++Scalar<> s4;
++Vector<> s5;
++Distribution<> s6;
++Vector<> s7;
 +AverageVector<> s8;
 +StandardDeviation<> s9;
 +AverageDeviation<> s10;
 +Scalar<> s11;
 +Distribution<> s12;
 +VectorDistribution<> s13;
 +VectorStandardDeviation<> s14;
 +VectorAverageDeviation<> s15;
 +Vector2d<> s16;
 +
 +Formula f1;
 +Formula f2;
 +Formula f3;
 +Value f4;
 +Value f5;
 +Formula f6;
 +Formula f7;
 +
-     bin1.activate();
 +ostream *outputStream = &cout;
 +
 +double
 +testfunc()
 +{
 +    return 9.8;
 +}
 +
 +class TestClass {
 +  public:
 +    double operator()() { return 9.7; }
 +};
 +
 +char *progname = "";
 +
 +void
 +usage()
 +{
 +    panic("incorrect usage.\n"
 +          "usage:\n"
 +          "\t%s [-t [-c] [-d]]\n", progname);
 +}
 +
 +int
 +main(int argc, char *argv[])
 +{
 +    bool descriptions = false;
 +    bool compat = false;
 +    bool text = false;
 +    string mysql_name;
 +    string mysql_host;
 +    string mysql_user = "binkertn";
 +    string mysql_passwd;
 +
 +    char c;
 +    progname = argv[0];
 +    while ((c = getopt(argc, argv, "cdh:P:p:s:tu:")) != -1) {
 +        switch (c) {
 +          case 'c':
 +            compat = true;
 +            break;
 +          case 'd':
 +            descriptions = true;
 +            break;
 +          case 'h':
 +            mysql_host = optarg;
 +            break;
 +          case 'P':
 +            mysql_passwd = optarg;
 +            break;
 +          case 's':
 +            mysql_name = optarg;
 +            break;
 +          case 't':
 +            text = true;
 +            break;
 +          case 'u':
 +            mysql_user = optarg;
 +            break;
 +          default:
 +            usage();
 +        }
 +    }
 +
 +    if (!text && (compat || descriptions))
 +        usage();
 +
 +    s5.init(5);
 +    s6.init(1, 100, 13);
 +    s7.init(7);
 +    s8.init(10);
 +    s12.init(1, 100, 13);
 +    s13.init(4, 0, 99, 10);
 +    s14.init(9);
 +    s15.init(10);
 +    s16.init(2, 9);
 +
 +    s1
 +        .name("Stat01")
 +        .desc("this is statistic 1")
 +        ;
 +
 +    s2
 +        .name("Stat02")
 +        .desc("this is statistic 2")
 +        .prereq(s11)
 +        ;
 +
 +    s3
 +        .name("Stat03")
 +        .desc("this is statistic 3")
 +        .prereq(f7)
 +        ;
 +
 +    s4
 +        .name("Stat04")
 +        .desc("this is statistic 4")
 +        .prereq(s11)
 +        ;
 +
 +    s5
 +        .name("Stat05")
 +        .desc("this is statistic 5")
 +        .prereq(s11)
 +        .subname(0, "foo1")
 +        .subname(1, "foo2")
 +        .subname(2, "foo3")
 +        .subname(3, "foo4")
 +        .subname(4, "foo5")
 +        ;
 +
 +    s6
 +        .name("Stat06")
 +        .desc("this is statistic 6")
 +        .prereq(s11)
 +        ;
 +
 +    s7
 +        .name("Stat07")
 +        .desc("this is statistic 7")
 +        .precision(1)
 +        .flags(pdf | total)
 +        .prereq(s11)
 +        ;
 +
 +    s8
 +        .name("Stat08")
 +        .desc("this is statistic 8")
 +        .precision(2)
 +        .prereq(s11)
 +        .subname(4, "blarg")
 +        ;
 +
 +    s9
 +        .name("Stat09")
 +        .desc("this is statistic 9")
 +        .precision(4)
 +        .prereq(s11)
 +        ;
 +
 +    s10
 +        .name("Stat10")
 +        .desc("this is statistic 10")
 +        .prereq(s11)
 +        ;
 +
 +    s12
 +        .name("Stat12")
 +        .desc("this is statistic 12")
 +        ;
 +
 +    s13
 +        .name("Stat13")
 +        .desc("this is statistic 13")
 +        ;
 +
 +    s14
 +        .name("Stat14")
 +        .desc("this is statistic 14")
 +        ;
 +
 +    s15
 +        .name("Stat15")
 +        .desc("this is statistic 15")
 +        ;
 +
 +    s16
 +        .name("Stat16")
 +        .desc("this is statistic 16")
 +        .flags(total)
 +        .subname(0, "sub0")
 +        .subname(1, "sub1")
 +        .ysubname(0, "y0")
 +        .ysubname(1, "y1")
 +        ;
 +
 +    f1
 +        .name("Formula1")
 +        .desc("this is formula 1")
 +        .prereq(s11)
 +        ;
 +
 +    f2
 +        .name("Formula2")
 +        .desc("this is formula 2")
 +        .prereq(s11)
 +        .precision(1)
 +        ;
 +
 +    f3
 +        .name("Formula3")
 +        .desc("this is formula 3")
 +        .prereq(s11)
 +        .subname(0, "bar1")
 +        .subname(1, "bar2")
 +        .subname(2, "bar3")
 +        .subname(3, "bar4")
 +        .subname(4, "bar5")
 +        ;
 +
 +    f4
 +        .functor(testfunc)
 +        .name("Formula4")
 +        .desc("this is formula 4")
 +        ;
 +
 +    TestClass testclass;
 +    f5
 +        .functor(testclass)
 +        .name("Formula5")
 +        .desc("this is formula 5")
 +        ;
 +
 +    f6
 +        .name("Formula6")
 +        .desc("this is formula 6")
 +        ;
 +
 +    f1 = s1 + s2;
 +    f2 = (-s1) / (-s2) * (-s3 + ULL(100) + s4);
 +    f3 = sum(s5) * s7;
 +    f6 += constant(10.0);
 +    f6 += s5[3];
 +    f7 = constant(1);
 +
 +    check();
 +    reset();
 +
-     bin2.activate();
 +    s16[1][0] = 1;
 +    s16[0][1] = 3;
 +    s16[0][0] = 2;
 +    s16[1][1] = 9;
 +    s16[1][1] += 9;
 +    s16[1][8] += 8;
 +    s16[1][7] += 7;
 +    s16[1][6] += 6;
 +    s16[1][5] += 5;
 +    s16[1][4] += 4;
 +
 +    s11 = 1;
 +    s3 = 9;
 +    s8[3] = 9;
 +    s15[0].sample(1234);
 +    s15[1].sample(1234);
 +    s15[2].sample(1234);
 +    s15[3].sample(1234);
 +    s15[4].sample(1234);
 +    s15[5].sample(1234);
 +    s15[6].sample(1234);
 +    s15[7].sample(1234);
 +    s15[8].sample(1234);
 +    s15[9].sample(1234);
 +
 +    s10.sample(1000000000);
 +    curTick += ULL(1000000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s10.sample(100000);
 +    s13[0].sample(12);
 +    s13[1].sample(29);
 +    s13[2].sample(12);
 +    s13[3].sample(29);
 +    s13[0].sample(42);
 +    s13[1].sample(29);
 +    s13[2].sample(42);
 +    s13[3].sample(32);
 +    s13[0].sample(52);
 +    s13[1].sample(49);
 +    s13[2].sample(42);
 +    s13[3].sample(25);
 +    s13[0].sample(32);
 +    s13[1].sample(49);
 +    s13[2].sample(22);
 +    s13[3].sample(49);
 +    s13[0].sample(62);
 +    s13[1].sample(99);
 +    s13[2].sample(72);
 +    s13[3].sample(23);
 +    s13[0].sample(52);
 +    s13[1].sample(78);
 +    s13[2].sample(69);
 +    s13[3].sample(49);
 +
 +    s14[0].sample(1234);
 +    s14[1].sample(4134);
 +    s14[4].sample(1213);
 +    s14[3].sample(1124);
 +    s14[2].sample(1243);
 +    s14[7].sample(1244);
 +    s14[4].sample(7234);
 +    s14[2].sample(9234);
 +    s14[3].sample(1764);
 +    s14[7].sample(1564);
 +    s14[3].sample(3234);
 +    s14[1].sample(2234);
 +    s14[5].sample(1234);
 +    s14[2].sample(4334);
 +    s14[2].sample(1234);
 +    s14[4].sample(4334);
 +    s14[6].sample(1234);
 +    s14[8].sample(8734);
 +    s14[1].sample(5234);
 +    s14[3].sample(8234);
 +    s14[7].sample(5234);
 +    s14[4].sample(4434);
 +    s14[3].sample(7234);
 +    s14[2].sample(1934);
 +    s14[1].sample(9234);
 +    s14[5].sample(5634);
 +    s14[3].sample(1264);
 +    s14[7].sample(5223);
 +    s14[0].sample(1234);
 +    s14[0].sample(5434);
 +    s14[3].sample(8634);
 +    s14[1].sample(1234);
 +
 +
 +    s15[0].sample(1234);
 +    s15[1].sample(4134);
 +    curTick += ULL(1000000);
 +    s15[4].sample(1213);
 +    curTick += ULL(1000000);
 +    s15[3].sample(1124);
 +    curTick += ULL(1000000);
 +    s15[2].sample(1243);
 +    curTick += ULL(1000000);
 +    s15[7].sample(1244);
 +    curTick += ULL(1000000);
 +    s15[4].sample(7234);
 +    s15[2].sample(9234);
 +    s15[3].sample(1764);
 +    s15[7].sample(1564);
 +    s15[3].sample(3234);
 +    s15[1].sample(2234);
 +    curTick += ULL(1000000);
 +    s15[5].sample(1234);
 +    curTick += ULL(1000000);
 +    s15[9].sample(4334);
 +    curTick += ULL(1000000);
 +    s15[2].sample(1234);
 +    curTick += ULL(1000000);
 +    s15[4].sample(4334);
 +    s15[6].sample(1234);
 +    curTick += ULL(1000000);
 +    s15[8].sample(8734);
 +    curTick += ULL(1000000);
 +    s15[1].sample(5234);
 +    curTick += ULL(1000000);
 +    s15[3].sample(8234);
 +    curTick += ULL(1000000);
 +    s15[7].sample(5234);
 +    s15[4].sample(4434);
 +    s15[3].sample(7234);
 +    s15[2].sample(1934);
 +    s15[1].sample(9234);
 +    curTick += ULL(1000000);
 +    s15[5].sample(5634);
 +    s15[3].sample(1264);
 +    s15[7].sample(5223);
 +    s15[0].sample(1234);
 +    s15[0].sample(5434);
 +    s15[3].sample(8634);
 +    curTick += ULL(1000000);
 +    s15[1].sample(1234);
 +
 +    s4 = curTick;
 +
 +    s8[3] = 99999;
 +
 +    s3 = 12;
 +    s3++;
 +    curTick += 9;
 +
 +    s1 = 9;
 +    s1 += 9;
 +    s1 -= 11;
 +    s1++;
 +    ++s1;
 +    s1--;
 +    --s1;
 +
 +    s2 = 9;
 +
 +    s5[0] += 1;
 +    s5[1] += 2;
 +    s5[2] += 3;
 +    s5[3] += 4;
 +    s5[4] += 5;
 +
 +    s7[0] = 10;
 +    s7[1] = 20;
 +    s7[2] = 30;
 +    s7[3] = 40;
 +    s7[4] = 50;
 +    s7[5] = 60;
 +    s7[6] = 70;
 +
 +    s6.sample(0);
 +    s6.sample(1);
 +    s6.sample(2);
 +    s6.sample(3);
 +    s6.sample(4);
 +    s6.sample(5);
 +    s6.sample(6);
 +    s6.sample(7);
 +    s6.sample(8);
 +    s6.sample(9);
 +
 +    s6.sample(10);
 +    s6.sample(10);
 +    s6.sample(10);
 +    s6.sample(10);
 +    s6.sample(10);
 +    s6.sample(10);
 +    s6.sample(10);
 +    s6.sample(10);
 +    s6.sample(11);
 +    s6.sample(19);
 +    s6.sample(20);
 +    s6.sample(20);
 +    s6.sample(21);
 +    s6.sample(21);
 +    s6.sample(31);
 +    s6.sample(98);
 +    s6.sample(99);
 +    s6.sample(99);
 +    s6.sample(99);
 +
 +    s7[0] = 700;
 +    s7[1] = 600;
 +    s7[2] = 500;
 +    s7[3] = 400;
 +    s7[4] = 300;
 +    s7[5] = 200;
 +    s7[6] = 100;
 +
 +    s9.sample(100);
 +    s9.sample(100);
 +    s9.sample(100);
 +    s9.sample(100);
 +    s9.sample(10);
 +    s9.sample(10);
 +    s9.sample(10);
 +    s9.sample(10);
 +    s9.sample(10);
 +
 +    curTick += 9;
 +    s4 = curTick;
 +    s6.sample(100);
 +    s6.sample(100);
 +    s6.sample(100);
 +    s6.sample(101);
 +    s6.sample(102);
 +
 +    s12.sample(100);
 +
 +    if (text) {
 +        Text out(cout);
 +        out.descriptions = descriptions;
 +        out.compat = compat;
 +        out();
 +    }
 +
 +    if (!mysql_name.empty()) {
 +        MySql out;
 +        out.connect(mysql_host, mysql_user, mysql_passwd, "m5stats",
 +                    mysql_name, "test");
 +        out();
 +    }
 +
 +    return 0;
 +}
Simple merge
Simple merge
Simple merge
Simple merge