summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SConscript23
-rw-r--r--src/arch/SConscript8
-rw-r--r--src/arch/alpha/ev5.cc4
-rw-r--r--src/arch/alpha/freebsd/system.cc12
-rw-r--r--src/arch/alpha/isa/decoder.isa2
-rw-r--r--src/arch/alpha/linux/system.cc33
-rw-r--r--src/arch/alpha/linux/system.hh14
-rw-r--r--src/arch/alpha/process.cc97
-rw-r--r--src/arch/alpha/process.hh12
-rw-r--r--src/arch/alpha/system.cc12
-rw-r--r--src/arch/alpha/tru64/system.cc10
-rwxr-xr-xsrc/arch/isa_parser.py6
-rw-r--r--src/arch/mips/SConscript2
-rw-r--r--src/arch/mips/isa/base.isa42
-rw-r--r--src/arch/mips/isa/bitfields.isa47
-rw-r--r--src/arch/mips/isa/decoder.isa1609
-rw-r--r--src/arch/mips/isa/formats/basic.isa33
-rw-r--r--src/arch/mips/isa/formats/branch.isa180
-rw-r--r--src/arch/mips/isa/formats/control.isa156
-rw-r--r--src/arch/mips/isa/formats/formats.isa35
-rw-r--r--src/arch/mips/isa/formats/fp.isa364
-rw-r--r--src/arch/mips/isa/formats/int.isa183
-rw-r--r--src/arch/mips/isa/formats/mem.isa132
-rw-r--r--src/arch/mips/isa/formats/mt.isa81
-rw-r--r--src/arch/mips/isa/formats/noop.isa36
-rw-r--r--src/arch/mips/isa/formats/tlbop.isa35
-rw-r--r--src/arch/mips/isa/formats/trap.isa43
-rw-r--r--src/arch/mips/isa/formats/unimp.isa32
-rw-r--r--src/arch/mips/isa/formats/unknown.isa41
-rw-r--r--src/arch/mips/isa/formats/util.isa54
-rw-r--r--src/arch/mips/isa/includes.isa35
-rw-r--r--src/arch/mips/isa/operands.isa30
-rw-r--r--src/arch/mips/isa_traits.cc73
-rw-r--r--src/arch/mips/linux/process.cc18
-rw-r--r--src/arch/mips/linux/process.hh2
-rw-r--r--src/arch/mips/process.cc114
-rw-r--r--src/arch/mips/process.hh13
-rw-r--r--src/arch/mips/regfile/float_regfile.hh45
-rw-r--r--src/arch/mips/utility.cc202
-rw-r--r--src/arch/mips/utility.hh13
-rw-r--r--src/arch/sparc/faults.cc2
-rw-r--r--src/arch/sparc/isa/includes.isa2
-rw-r--r--src/arch/sparc/process.cc98
-rw-r--r--src/arch/sparc/process.hh9
-rw-r--r--src/arch/sparc/regfile.hh28
-rw-r--r--src/base/statistics.cc68
-rw-r--r--src/base/statistics.hh1164
-rw-r--r--src/base/stats/mysql.cc96
-rw-r--r--src/base/stats/mysql.hh3
-rw-r--r--src/base/stats/statdb.cc12
-rw-r--r--src/base/stats/statdb.hh6
-rw-r--r--src/base/stats/text.cc20
-rw-r--r--src/base/stats/text.hh1
-rw-r--r--src/cpu/base.cc8
-rw-r--r--src/cpu/o3/alpha_cpu_impl.hh3
-rw-r--r--src/cpu/simple/base.cc5
-rw-r--r--src/cpu/thread_context.hh2
-rw-r--r--src/cpu/trace/opt_cpu.cc2
-rw-r--r--src/cpu/trace/trace_cpu.cc2
-rw-r--r--src/kern/kernel_stats.cc18
-rw-r--r--src/kern/kernel_stats.hh80
-rw-r--r--src/kern/system_events.cc32
-rw-r--r--src/kern/system_events.hh32
-rw-r--r--src/python/SConscript28
-rw-r--r--src/python/m5/__init__.py184
-rw-r--r--src/python/m5/config.py254
-rw-r--r--src/python/m5/multidict.py24
-rw-r--r--src/python/m5/objects/AlphaConsole.py2
-rw-r--r--src/python/m5/objects/AlphaFullCPU.py3
-rw-r--r--src/python/m5/objects/AlphaTLB.py2
-rw-r--r--src/python/m5/objects/BadDevice.py2
-rw-r--r--src/python/m5/objects/BaseCPU.py4
-rw-r--r--src/python/m5/objects/BaseCache.py2
-rw-r--r--src/python/m5/objects/Bridge.py2
-rw-r--r--src/python/m5/objects/Bus.py2
-rw-r--r--src/python/m5/objects/CoherenceProtocol.py2
-rw-r--r--src/python/m5/objects/Device.py2
-rw-r--r--src/python/m5/objects/DiskImage.py2
-rw-r--r--src/python/m5/objects/Ethernet.py3
-rw-r--r--src/python/m5/objects/FUPool.py5
-rw-r--r--src/python/m5/objects/Ide.py2
-rw-r--r--src/python/m5/objects/IntrControl.py2
-rw-r--r--src/python/m5/objects/MemObject.py2
-rw-r--r--src/python/m5/objects/MemTest.py2
-rw-r--r--src/python/m5/objects/OzoneCPU.py3
-rw-r--r--src/python/m5/objects/Pci.py2
-rw-r--r--src/python/m5/objects/PhysicalMemory.py2
-rw-r--r--src/python/m5/objects/Platform.py2
-rw-r--r--src/python/m5/objects/Process.py2
-rw-r--r--src/python/m5/objects/Repl.py2
-rw-r--r--src/python/m5/objects/Root.py2
-rw-r--r--src/python/m5/objects/SimConsole.py2
-rw-r--r--src/python/m5/objects/SimpleDisk.py2
-rw-r--r--src/python/m5/objects/SimpleOzoneCPU.py3
-rw-r--r--src/python/m5/objects/System.py5
-rw-r--r--src/python/m5/objects/Tsunami.py2
-rw-r--r--src/python/m5/objects/Uart.py3
-rw-r--r--src/sim/eventq.cc13
-rw-r--r--src/sim/eventq.hh8
-rw-r--r--src/sim/host.hh2
-rw-r--r--src/sim/main.cc270
-rw-r--r--src/sim/process.cc144
-rw-r--r--src/sim/process.hh10
-rw-r--r--src/sim/pseudo_inst.cc4
-rw-r--r--src/sim/root.cc3
-rw-r--r--src/sim/serialize.cc2
-rw-r--r--src/sim/sim_events.cc39
-rw-r--r--src/sim/sim_events.hh22
-rw-r--r--src/sim/sim_exit.hh17
-rw-r--r--src/sim/syscall_emul.cc34
-rw-r--r--src/sim/syscall_emul.hh5
-rw-r--r--src/sim/system.cc16
-rw-r--r--src/sim/system.hh7
-rw-r--r--src/unittest/stattest.cc14
114 files changed, 3451 insertions, 3298 deletions
diff --git a/src/SConscript b/src/SConscript
index d29ecb7bb..a1c18711c 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -109,12 +109,12 @@ base_sources = Split('''
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_exit.cc
sim/sim_object.cc
sim/startup.cc
sim/stat_context.cc
@@ -219,7 +219,6 @@ full_system_sources = Split('''
dev/uart.cc
dev/uart8250.cc
- kern/kernel_binning.cc
kern/kernel_stats.cc
kern/system_events.cc
kern/linux/events.cc
@@ -286,14 +285,18 @@ 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', duplicate = False)
+arch_sources = SConscript('arch/SConscript', exports = 'env')
-cpu_sources = SConscript('cpu/SConscript',
- exports = 'env', duplicate = False)
+cpu_sources = SConscript('cpu/SConscript', exports = 'env')
# This is outside of cpu/SConscript since the source directory isn't
# underneath 'cpu'.
@@ -328,7 +331,7 @@ env.Command(Split('base/traceflags.hh base/traceflags.cc'),
'base/traceflags.py',
'python $SOURCE $TARGET.base')
-SConscript('python/SConscript', exports = ['env'], duplicate=0)
+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
@@ -351,12 +354,6 @@ def make_objs(sources, env):
#
###################################################
-# 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='.')
-
# List of constructed environments to pass back to SConstruct
envList = []
diff --git a/src/arch/SConscript b/src/arch/SConscript
index dd616174c..ff460dafd 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -28,7 +28,7 @@
#
# Authors: Steve Reinhardt
-import os.path
+import os.path, sys
# Import build environment variable from SConstruct.
Import('env')
@@ -134,7 +134,8 @@ def isa_desc_emitter(target, source, env):
return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source)
# Pieces are in place, so create the builder.
-isa_desc_builder = Builder(action='python2.4 $SOURCES $TARGET.dir $CPU_MODELS',
+python = sys.executable # use same Python binary used to run scons
+isa_desc_builder = Builder(action=python + ' $SOURCES $TARGET.dir $CPU_MODELS',
emitter = isa_desc_emitter)
env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
@@ -146,7 +147,6 @@ env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
isa = env['TARGET_ISA'] # someday this may be a list of ISAs
# Let the target architecture define what additional sources it needs
-sources += SConscript(os.path.join(isa, 'SConscript'),
- exports = 'env', duplicate = False)
+sources += SConscript(os.path.join(isa, 'SConscript'), exports = 'env')
Return('sources')
diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc
index 247c5f56e..ae3b668ea 100644
--- a/src/arch/alpha/ev5.cc
+++ b/src/arch/alpha/ev5.cc
@@ -41,7 +41,7 @@
#include "cpu/thread_context.hh"
#include "kern/kernel_stats.hh"
#include "sim/debug.hh"
-#include "sim/sim_events.hh"
+#include "sim/sim_exit.hh"
#if FULL_SYSTEM
@@ -575,7 +575,7 @@ SimpleThread::simPalCheck(int palFunc)
case PAL::halt:
halt();
if (--System::numSystemsRunning == 0)
- new SimExitEvent("all cpus halted");
+ exitSimLoop("all cpus halted");
break;
case PAL::bpt:
diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc
index 91f8b5af1..7cf68e0db 100644
--- a/src/arch/alpha/freebsd/system.cc
+++ b/src/arch/alpha/freebsd/system.cc
@@ -109,10 +109,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
Param<uint64_t> system_type;
Param<uint64_t> system_rev;
- Param<bool> bin;
- VectorParam<string> binned_fns;
- Param<bool> bin_int;
-
END_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
@@ -127,10 +123,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
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),
- 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)
+ INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
END_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
@@ -148,9 +141,6 @@ CREATE_SIM_OBJECT(FreebsdAlphaSystem)
p->readfile = readfile;
p->system_type = system_type;
p->system_rev = system_rev;
- p->bin = bin;
- p->binned_fns = binned_fns;
- p->bin_int = bin_int;
return new FreebsdAlphaSystem(p);
}
diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa
index dd29e47e4..2ecd9f5ad 100644
--- a/src/arch/alpha/isa/decoder.isa
+++ b/src/arch/alpha/isa/decoder.isa
@@ -697,7 +697,7 @@ decode OPCODE default Unknown::unknown() {
0x00: decode PALFUNC {
format EmulatedCallPal {
0x00: halt ({{
- SimExit(curTick, "halt instruction encountered");
+ exitSimLoop(curTick, "halt instruction encountered");
}}, IsNonSpeculative);
0x83: callsys({{
xc->syscall(R0);
diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc
index 3e061bba8..9fe63c390 100644
--- a/src/arch/alpha/linux/system.cc
+++ b/src/arch/alpha/linux/system.cc
@@ -137,24 +137,6 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
} else {
printThreadEvent = NULL;
}
-
- 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");
- }
}
LinuxAlphaSystem::~LinuxAlphaSystem()
@@ -168,9 +150,6 @@ LinuxAlphaSystem::~LinuxAlphaSystem()
delete debugPrintkEvent;
delete idleStartEvent;
delete printThreadEvent;
- delete intStartEvent;
- delete intEndEvent;
- delete intEndEvent2;
}
@@ -224,10 +203,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
Param<uint64_t> system_type;
Param<uint64_t> system_rev;
- Param<bool> bin;
- VectorParam<string> binned_fns;
- Param<bool> bin_int;
-
END_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
@@ -242,10 +217,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
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),
- 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)
+ INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
END_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
@@ -263,9 +235,6 @@ CREATE_SIM_OBJECT(LinuxAlphaSystem)
p->readfile = readfile;
p->system_type = system_type;
p->system_rev = system_rev;
- p->bin = bin;
- p->binned_fns = binned_fns;
- p->bin_int = bin_int;
return new LinuxAlphaSystem(p);
}
diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh
index c03586ac5..6921ba820 100644
--- a/src/arch/alpha/linux/system.hh
+++ b/src/arch/alpha/linux/system.hh
@@ -45,7 +45,7 @@ using namespace AlphaISA;
using namespace Linux;
/**
- * This class contains linux specific system code (Loading, Events, Binning).
+ * 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.
*/
@@ -124,18 +124,6 @@ class LinuxAlphaSystem : public AlphaSystem
*/
PrintThreadInfo *printThreadEvent;
- /**
- * Event to bin Interrupts seperately from kernel code
- */
- InterruptStartEvent *intStartEvent;
-
- /**
- * Event to bin Interrupts seperately from kernel code
- */
- InterruptEndEvent *intEndEvent;
- InterruptEndEvent *intEndEvent2;
- InterruptEndEvent *intEndEvent3;
-
/** Grab the PCBB of the idle process when it starts */
IdleStartEvent *idleStartEvent;
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index 4c0c68761..970292cd8 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -31,55 +31,15 @@
#include "arch/alpha/constants.hh"
#include "arch/alpha/process.hh"
-#include "arch/alpha/linux/process.hh"
-#include "arch/alpha/tru64/process.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
-#include "sim/builder.hh"
#include "sim/system.hh"
using namespace AlphaISA;
using namespace std;
-AlphaLiveProcess *
-AlphaLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
- int stdout_fd, int stderr_fd, std::string executable,
- std::vector<std::string> &argv, std::vector<std::string> &envp)
-{
- AlphaLiveProcess *process = NULL;
-
- ObjectFile *objFile = createObjectFile(executable);
- if (objFile == NULL) {
- fatal("Can't load object file %s", executable);
- }
-
-
- if (objFile->getArch() != ObjectFile::Alpha)
- fatal("Object file does not match architecture.");
- switch (objFile->getOpSys()) {
- case ObjectFile::Tru64:
- process = new AlphaTru64Process(nm, objFile, system,
- stdin_fd, stdout_fd, stderr_fd,
- argv, envp);
- break;
-
- case ObjectFile::Linux:
- process = new AlphaLinuxProcess(nm, objFile, system,
- stdin_fd, stdout_fd, stderr_fd,
- argv, envp);
- break;
-
- default:
- fatal("Unknown/unsupported operating system.");
- }
-
- if (process == NULL)
- fatal("Unknown error creating process object.");
- return process;
-}
-
AlphaLiveProcess::AlphaLiveProcess(const std::string &nm, ObjectFile *objFile,
System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv, std::vector<std::string> &envp)
@@ -111,60 +71,3 @@ AlphaLiveProcess::startup()
}
-
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess)
-
- VectorParam<string> cmd;
- Param<string> executable;
- Param<string> input;
- Param<string> output;
- VectorParam<string> env;
- SimObjectParam<System *> system;
-
-END_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess)
-
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess)
-
- INIT_PARAM(cmd, "command line (executable plus arguments)"),
- INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
- INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
- INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
- INIT_PARAM(env, "environment settings"),
- INIT_PARAM(system, "system")
-
-END_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess)
-
-
-CREATE_SIM_OBJECT(AlphaLiveProcess)
-{
- string in = input;
- string out = output;
-
- // initialize file descriptors to default: same as simulator
- int stdin_fd, stdout_fd, stderr_fd;
-
- if (in == "stdin" || in == "cin")
- stdin_fd = STDIN_FILENO;
- else
- stdin_fd = Process::openInputFile(input);
-
- if (out == "stdout" || out == "cout")
- stdout_fd = STDOUT_FILENO;
- else if (out == "stderr" || out == "cerr")
- stdout_fd = STDERR_FILENO;
- else
- stdout_fd = Process::openOutputFile(out);
-
- stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
-
- return AlphaLiveProcess::create(getInstanceName(), system,
- stdin_fd, stdout_fd, stderr_fd,
- (string)executable == "" ? cmd[0] : executable,
- cmd, env);
-}
-
-
-REGISTER_SIM_OBJECT("AlphaLiveProcess", AlphaLiveProcess)
-
diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh
index 7fa913cad..5d5c9a52e 100644
--- a/src/arch/alpha/process.hh
+++ b/src/arch/alpha/process.hh
@@ -49,18 +49,6 @@ class AlphaLiveProcess : public LiveProcess
std::vector<std::string> &envp);
void startup();
-
- public:
- // this function is used to create the LiveProcess object, since
- // we can't tell which subclass of LiveProcess to use until we
- // open and look at the object file.
- static AlphaLiveProcess *create(const std::string &nm,
- System *_system,
- int stdin_fd, int stdout_fd, int stderr_fd,
- std::string executable,
- std::vector<std::string> &argv,
- std::vector<std::string> &envp);
-
};
diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc
index a68e440b0..3aaba7d58 100644
--- a/src/arch/alpha/system.cc
+++ b/src/arch/alpha/system.cc
@@ -232,10 +232,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
Param<uint64_t> system_type;
Param<uint64_t> system_rev;
- Param<bool> bin;
- VectorParam<std::string> binned_fns;
- Param<bool> bin_int;
-
END_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
@@ -250,10 +246,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
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),
- 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)
+ INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
END_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
@@ -271,9 +264,6 @@ CREATE_SIM_OBJECT(AlphaSystem)
p->readfile = readfile;
p->system_type = system_type;
p->system_rev = system_rev;
- p->bin = bin;
- p->binned_fns = binned_fns;
- p->bin_int = bin_int;
return new AlphaSystem(p);
}
diff --git a/src/arch/alpha/tru64/system.cc b/src/arch/alpha/tru64/system.cc
index 8d9a53273..6c0edc1ee 100644
--- a/src/arch/alpha/tru64/system.cc
+++ b/src/arch/alpha/tru64/system.cc
@@ -107,9 +107,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
Param<uint64_t> system_type;
Param<uint64_t> system_rev;
- Param<bool> bin;
- VectorParam<string> binned_fns;
-
END_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
@@ -124,9 +121,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
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),
- 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")
+ INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1)
END_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
@@ -144,9 +139,6 @@ CREATE_SIM_OBJECT(Tru64AlphaSystem)
p->readfile = readfile;
p->system_type = system_type;
p->system_rev = system_rev;
- p->bin = bin;
- p->binned_fns = binned_fns;
- p->bin_int = false;
return new Tru64AlphaSystem(p);
}
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index 22baaf98e..4d522e18a 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -25,6 +25,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Steve Reinhardt
+# Korey Sewell
import os
import sys
@@ -1181,6 +1182,11 @@ class IntRegOperand(Operand):
if (self.size == self.dflt_size):
return '%s = xc->readIntReg(this, %d);\n' % \
(self.base_name, self.src_reg_idx)
+ elif (self.size > self.dflt_size):
+ int_reg_val = 'xc->readIntReg(this, %d)' % (self.src_reg_idx)
+ if (self.is_signed):
+ int_reg_val = 'sext<%d>(%s)' % (self.dflt_size, int_reg_val)
+ return '%s = %s;\n' % (self.base_name, int_reg_val)
else:
return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \
(self.base_name, self.src_reg_idx, self.size-1)
diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript
index 0365f5373..6295a6c11 100644
--- a/src/arch/mips/SConscript
+++ b/src/arch/mips/SConscript
@@ -28,6 +28,7 @@
#
# Authors: Gabe Black
# Steve Reinhardt
+# Korey Sewell
import os
import sys
@@ -46,6 +47,7 @@ Import('env')
base_sources = Split('''
faults.cc
isa_traits.cc
+ utility.cc
''')
# Full-system sources
diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa
index b2a31c018..b733da7da 100644
--- a/src/arch/mips/isa/base.isa
+++ b/src/arch/mips/isa/base.isa
@@ -1,5 +1,33 @@
// -*- mode:c++ -*-
+// 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: Korey Sewell
+
////////////////////////////////////////////////////////////////////
//
// Base class for MIPS instructions, and some support functions
@@ -18,16 +46,6 @@ output header {{
{
protected:
- /// Make MipsISA register dependence tags directly visible in
- /// this class and derived classes. Maybe these should really
- /// live here and not in the MipsISA namespace.
- /*enum DependenceTags {
- FP_Base_DepTag = MipsISA::FP_Base_DepTag,
- Fpcr_DepTag = MipsISA::Fpcr_DepTag,
- Uniq_DepTag = MipsISA::Uniq_DepTag,
- IPR_Base_DepTag = MipsISA::IPR_Base_DepTag
- };*/
-
// Constructor
MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
: StaticInst(mnem, _machInst, __opClass)
@@ -67,12 +85,12 @@ output decoder {{
}
if(_numSrcRegs > 0) {
- ss << ",";
+ ss << ", ";
printReg(ss, _srcRegIdx[0]);
}
if(_numSrcRegs > 1) {
- ss << ",";
+ ss << ", ";
printReg(ss, _srcRegIdx[1]);
}
diff --git a/src/arch/mips/isa/bitfields.isa b/src/arch/mips/isa/bitfields.isa
index e1124a591..e8d4578c7 100644
--- a/src/arch/mips/isa/bitfields.isa
+++ b/src/arch/mips/isa/bitfields.isa
@@ -1,5 +1,33 @@
// -*- mode:c++ -*-
+// 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: Korey Sewell
+
////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
@@ -17,20 +45,19 @@ def bitfield FUNCTION < 5: 0>;
def bitfield FUNCTION_HI < 5: 3>;
def bitfield FUNCTION_LO < 2: 0>;
-// Integer operate format
-def bitfield RT <20:16>;
-def bitfield RT_HI <20:19>;
-def bitfield RT_LO <18:16>;
-
def bitfield RS <25:21>;
def bitfield RS_MSB <25:25>;
def bitfield RS_HI <25:24>;
def bitfield RS_LO <23:21>;
-def bitfield RS_SRL <25:22>;
-
+def bitfield RS_SRL <25:22>;
+def bitfield RS_RT <25:16>;
+def bitfield RT <20:16>;
+def bitfield RT_HI <20:19>;
+def bitfield RT_LO <18:16>;
+def bitfield RT_RD <20:11>;
def bitfield RD <15:11>;
-def bitfield INTIMM <15: 0>; // integer immediate (literal)
+def bitfield INTIMM <15: 0>;
// Floating-point operate format
def bitfield FMT <25:21>;
@@ -67,5 +94,9 @@ def bitfield HINT <10: 6>;
def bitfield SYSCALLCODE <25: 6>;
def bitfield TRAPCODE <15:13>;
+// EXT/INS instructions
+def bitfield MSB <15:11>;
+def bitfield LSB <10: 6>;
+
// M5 instructions
def bitfield M5FUNC <7:0>;
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index 1454aba39..a64f74c4f 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -1,4 +1,32 @@
- // -*- mode:c++ -*-
+// -*- mode:c++ -*-
+
+// 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: Korey Sewell
////////////////////////////////////////////////////////////////////
//
@@ -6,41 +34,33 @@
// -----------------------------
// The following instructions are specified in the MIPS32 ISA
// Specification. Decoding closely follows the style specified
-// in the MIPS32 ISAthe specification document starting with Table
+// in the MIPS32 ISA specification document starting with Table
// A-2 (document available @ www.mips.com)
//
-//@todo: Distinguish "unknown/future" use insts from "reserved"
-// ones
decode OPCODE_HI default Unknown::unknown() {
-
- // Derived From ... Table A-2 MIPS32 ISA Manual
+ //Table A-2
0x0: decode OPCODE_LO {
-
0x0: decode FUNCTION_HI {
0x0: decode FUNCTION_LO {
0x1: decode MOVCI {
format BasicOp {
- 0: movf({{ if (getFPConditionCode(FCSR, CC) == 0) Rd = Rs}});
- 1: movt({{ if (getFPConditionCode(FCSR, CC) == 1) Rd = Rs}});
+ 0: movf({{ Rd = (getCondCode(FCSR, CC) == 0) ? Rd : Rs; }});
+ 1: movt({{ Rd = (getCondCode(FCSR, CC) == 1) ? Rd : Rs; }});
}
}
format BasicOp {
-
- //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
- //are used to distinguish among the SLL, NOP, SSNOP and EHB functions.
+ //Table A-3 Note: "Specific encodings of the rd, rs, and
+ //rt fields are used to distinguish SLL, SSNOP, and EHB
+ //functions
0x0: decode RS {
- 0x0: decode RT { //fix Nop traditional vs. Nop converted disassembly later
- 0x0: decode RD default Nop::nop(){
- 0x0: decode SA {
- 0x1: ssnop({{ ; }}); //really sll r0,r0,1
- 0x3: ehb({{ ; }}); //really sll r0,r0,3
- }
- }
-
- default: sll({{ Rd = Rt.uw << SA; }});
+ 0x0: decode RT_RD {
+ 0x0: decode SA default Nop::nop(){
+ 0x1: WarnUnimpl::ssnop();
+ 0x3: WarnUnimpl::ehb();
+ }
+ default: sll({{ Rd = Rt.uw << SA; }});
}
-
}
0x2: decode RS_SRL {
@@ -55,7 +75,6 @@ decode OPCODE_HI default Unknown::unknown() {
0x3: decode RS {
0x0: sra({{
uint32_t temp = Rt >> SA;
-
if ( (Rt & 0x80000000) > 0 ) {
uint32_t mask = 0x80000000;
for(int i=0; i < SA; i++) {
@@ -63,7 +82,6 @@ decode OPCODE_HI default Unknown::unknown() {
mask = mask >> 1;
}
}
-
Rd = temp;
}});
}
@@ -96,37 +114,36 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x1: decode FUNCTION_LO {
-
- //Table A-3 Note: "Specific encodings of the hint field are used
- //to distinguish JR from JR.HB and JALR from JALR.HB"
+ //Table A-3 Note: "Specific encodings of the hint field are
+ //used to distinguish JR from JR.HB and JALR from JALR.HB"
format Jump {
0x0: decode HINT {
- 0:jr({{ NNPC = Rs & ~1; }},IsReturn);
-
- 1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn);
+ 0x1: jr_hb({{ NNPC = Rs & ~1; }}, IsReturn, ClearHazards);
+ default: jr({{ NNPC = Rs & ~1; }}, IsReturn);
}
0x1: decode HINT {
- 0: jalr({{ Rd = NNPC; NNPC = Rs; }},IsCall,IsReturn);
-
- 1: jalr_hb({{ Rd = NNPC; NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
+ 0x1: jalr_hb({{ Rd = NNPC; NNPC = Rs; }}, IsCall, Link
+ , ClearHazards);
+ default: jalr({{ Rd = NNPC; NNPC = Rs; }}, IsCall,
+ Link);
}
}
format BasicOp {
- 0x2: movz({{ if (Rt == 0) Rd = Rs; }});
- 0x3: movn({{ if (Rt != 0) Rd = Rs; }});
+ 0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
+ 0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
+ 0x4: syscall({{ xc->syscall(R2); }}, IsNonSpeculative);
+ 0x7: sync({{ ; }}, IsMemBarrier);
}
- format BasicOp {
- 0x4: syscall({{ xc->syscall(R2); }},IsNonSpeculative);
- 0x5: break({{ panic("Not implemented break yet"); }},IsNonSpeculative);
- 0x7: sync({{ panic("Not implemented sync yet"); }},IsNonSpeculative);
+ format FailUnimpl {
+ 0x5: break();
}
}
0x2: decode FUNCTION_LO {
- format BasicOp {
+ format HiLoMiscOp {
0x0: mfhi({{ Rd = HI; }});
0x1: mthi({{ HI = Rs; }});
0x2: mflo({{ Rd = LO; }});
@@ -135,24 +152,16 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x3: decode FUNCTION_LO {
- format IntOp {
- 0x0: mult({{
- int64_t temp1 = Rs.sd * Rt.sd;
- HI = temp1<63:32>;
- LO = temp1<31:0>;
- }});
-
- 0x1: multu({{
- uint64_t temp1 = Rs.ud * Rt.ud;
- HI = temp1<63:32>;
- LO = temp1<31:0>;
- }});
+ format HiLoOp {
+ 0x0: mult({{ val = Rs.sd * Rt.sd; }});
+ 0x1: multu({{ val = Rs.ud * Rt.ud; }});
+ }
+ format HiLoMiscOp {
0x2: div({{
HI = Rs.sd % Rt.sd;
LO = Rs.sd / Rt.sd;
}});
-
0x3: divu({{
HI = Rs.ud % Rt.ud;
LO = Rs.ud / Rt.ud;
@@ -201,11 +210,8 @@ decode OPCODE_HI default Unknown::unknown() {
format Branch {
0x0: bltz({{ cond = (Rs.sw < 0); }});
0x1: bgez({{ cond = (Rs.sw >= 0); }});
- }
-
- format BranchLikely {
- 0x2: bltzl({{ cond = (Rs.sw < 0); }});
- 0x3: bgezl({{ cond = (Rs.sw >= 0); }});
+ 0x2: bltzl({{ cond = (Rs.sw < 0); }}, Likely);
+ 0x3: bgezl({{ cond = (Rs.sw >= 0); }}, Likely);
}
}
@@ -222,13 +228,13 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: decode REGIMM_LO {
format Branch {
- 0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn);
- 0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn);
- }
-
- format BranchLikely {
- 0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn);
- 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn);
+ 0x0: bltzal({{ cond = (Rs.sw < 0); }}, Link);
+ 0x1: decode RS {
+ 0x0: bal ({{ cond = 1; }}, IsCall, Link);
+ default: bgezal({{ cond = (Rs.sw >= 0); }}, Link);
+ }
+ 0x2: bltzall({{ cond = (Rs.sw < 0); }}, Link, Likely);
+ 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, Link, Likely);
}
}
@@ -241,25 +247,23 @@ decode OPCODE_HI default Unknown::unknown() {
format Jump {
0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}});
-
- 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn);
+ 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }}, IsCall,
+ Link);
}
format Branch {
- 0x4: beq({{ cond = (Rs.sw == Rt.sw); }});
- 0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
- 0x6: decode RT {
- 0x0: blez({{ cond = (Rs.sw <= 0); }});
- }
-
- 0x7: decode RT {
- 0x0: bgtz({{ cond = (Rs.sw > 0); }});
+ 0x4: decode RS_RT {
+ 0x0: b({{ cond = 1; }});
+ default: beq({{ cond = (Rs.sw == Rt.sw); }});
}
+ 0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
+ 0x6: blez({{ cond = (Rs.sw <= 0); }});
+ 0x7: bgtz({{ cond = (Rs.sw > 0); }});
}
}
0x1: decode OPCODE_LO {
- format IntOp {
+ format IntImmOp {
0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}});
0x1: addiu({{ Rt.sw = Rs.sw + imm;}});
0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }});
@@ -275,112 +279,47 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x2: decode OPCODE_LO {
-
//Table A-11 MIPS32 COP0 Encoding of rs Field
0x0: decode RS_MSB {
0x0: decode RS {
- format System {
- 0x0: mfc0({{
- //uint64_t reg_num = Rd.uw;
-
- Rt = xc->readMiscReg(RD << 5 | SEL);
- }});
-
- 0x4: mtc0({{
- //uint64_t reg_num = Rd.uw;
-
- xc->setMiscReg(RD << 5 | SEL,Rt);
- }});
-
- 0x8: mftr({{
- //The contents of the coprocessor 0 register specified by the
- //combination of rd and sel are loaded into general register
- //rt. Note that not all coprocessor 0 registers support the
- //sel field. In those instances, the sel field must be zero.
-
- //MT Code Needed Here
-
- }});
-
- 0xC: mttr({{
- //The contents of the coprocessor 0 register specified by the
- //combination of rd and sel are loaded into general register
- //rt. Note that not all coprocessor 0 registers support the
- //sel field. In those instances, the sel field must be zero.
-
- //MT Code Needed Here
- }});
-
-
- 0xA: rdpgpr({{
- //Accessing Previous Shadow Set Register Number
- //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/;
- //uint64_t reg_num = Rt.uw;
-
- //Rd = xc->regs.IntRegFile[prev];
- //Rd = xc->shadowIntRegFile[prev][reg_num];
- }});
+ format CP0Control {
+ 0x0: mfc0({{ Rt = xc->readMiscReg(RD << 5 | SEL); }});
+ 0x4: mtc0({{ xc->setMiscReg(RD << 5 | SEL, Rt); }});
+ }
+ format MipsMT {
+ 0x8: mftr();
+ 0xC: mttr();
0xB: decode RD {
-
0x0: decode SC {
- 0x0: dvpe({{
- Rt.sw = xc->readMiscReg(MVPControl);
- xc->setMiscReg(MVPControl,0);
- }});
-
- 0x1: evpe({{
- Rt.sw = xc->readMiscReg(MVPControl);
- xc->setMiscReg(MVPControl,1);
- }});
+ 0x0: dvpe();
+ 0x1: evpe();
}
-
0x1: decode SC {
- 0x0: dmt({{
- Rt.sw = xc->readMiscReg(VPEControl);
- xc->setMiscReg(VPEControl,0);
- }});
-
- 0x1: emt({{
- Rt.sw = xc->readMiscReg(VPEControl);
- xc->setMiscReg(VPEControl,1);
- }});
- }
-
- 0xC: decode SC {
- 0x0: di({{
- Rt.sw = xc->readMiscReg(Status);
- xc->setMiscReg(Status,0);
- }});
-
- 0x1: ei({{
- Rt.sw = xc->readMiscReg(Status);
- xc->setMiscReg(Status,1);
- }});
+ 0x0: dmt();
+ 0x1: emt();
+ 0xC: decode SC {
+ 0x0: di();
+ 0x1: ei();
+ }
}
}
+ }
- 0xE: wrpgpr({{
- //Accessing Previous Shadow Set Register Number
- //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/);
- //uint64_t reg_num = Rd.uw;
-
- //xc->regs.IntRegFile[prev];
- //xc->shadowIntRegFile[prev][reg_num] = Rt;
- }});
+ format FailUnimpl {
+ 0xA: rdpgpr();
+ 0xE: wrpgpr();
}
}
//Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
0x1: decode FUNCTION {
- format System {
- 0x01: tlbr({{ }});
- 0x02: tlbwi({{ }});
- 0x06: tlbwr({{ }});
- 0x08: tlbp({{ }});
- }
+ format FailUnimpl {
+ 0x01: tlbr();
+ 0x02: tlbwi();
+ 0x06: tlbwr();
+ 0x08: tlbp();
- format WarnUnimpl {
0x18: eret();
0x1F: deret();
0x20: wait();
@@ -393,18 +332,9 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode RS_HI {
0x0: decode RS_LO {
- format FloatOp {
+ format CP1Control {
0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }});
- 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
- 0x4: mtc1 ({{ Fs.uw = Rt.uw; }});
- 0x7: mthc1({{
- uint64_t fs_hi = Rt.uw;
- uint64_t fs_lo = Fs.ud & 0x0000FFFF;
- Fs.ud = fs_hi << 32 | fs_lo;
- }});
- }
- format System {
0x2: cfc1({{
switch (FS)
{
@@ -424,11 +354,14 @@ decode OPCODE_HI default Unknown::unknown() {
Rt = FCSR;
break;
default:
- panic("FP Control Value (%d) Not Available. Ignoring Access to"
- "Floating Control Status Register",FS);
+ panic("FP Control Value (%d) Not Valid");
}
}});
+ 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
+
+ 0x4: mtc1 ({{ Fs.uw = Rt.uw; }});
+
0x6: ctc1({{
switch (FS)
{
@@ -464,21 +397,29 @@ decode OPCODE_HI default Unknown::unknown() {
"Floating Control Status Register", FS);
}
}});
+
+ 0x7: mthc1({{
+ uint64_t fs_hi = Rt.uw;
+ uint64_t fs_lo = Fs.ud & 0x0FFFFFFFF;
+ Fs.ud = (fs_hi << 32) | fs_lo;
+ }});
+
}
}
0x1: decode ND {
- 0x0: decode TF {
- format Branch {
- 0x0: bc1f({{ cond = (getFPConditionCode(FCSR,CC) == 0); }});
- 0x1: bc1t({{ cond = (getFPConditionCode(FCSR,CC) == 1); }});
+ format Branch {
+ 0x0: decode TF {
+ 0x0: bc1f({{ cond = getCondCode(FCSR, BRANCH_CC) == 0;
+ }});
+ 0x1: bc1t({{ cond = getCondCode(FCSR, BRANCH_CC) == 1;
+ }});
}
- }
-
- 0x1: decode TF {
- format BranchLikely {
- 0x0: bc1fl({{ cond = (getFPConditionCode(FCSR,CC) == 0); }});
- 0x1: bc1tl({{ cond = (getFPConditionCode(FCSR,CC) == 1); }});
+ 0x1: decode TF {
+ 0x0: bc1fl({{ cond = getCondCode(FCSR, BRANCH_CC) == 0;
+ }}, Likely);
+ 0x1: bc1tl({{ cond = getCondCode(FCSR, BRANCH_CC) == 1;
+ }}, Likely);
}
}
}
@@ -486,9 +427,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode RS_HI {
0x2: decode RS_LO {
-
//Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
- //(( single-word ))
+ //(( single-precision floating point))
0x0: decode FUNCTION_HI {
0x0: decode FUNCTION_LO {
format FloatOp {
@@ -499,194 +439,102 @@ decode OPCODE_HI default Unknown::unknown() {
0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf);}});
0x5: abs_s({{ Fd.sf = fabs(Fs.sf);}});
0x6: mov_s({{ Fd.sf = Fs.sf;}});
- 0x7: neg_s({{ Fd.sf = -1 * Fs.sf;}});
+ 0x7: neg_s({{ Fd.sf = -Fs.sf;}});
}
}
0x1: decode FUNCTION_LO {
- format Float64Op {
- 0x0: round_l_s({{
- Fd.ud = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_LONG);
- }});
-
- 0x1: trunc_l_s({{
- Fd.ud = fpConvert(truncFP(Fs.sf), SINGLE_TO_LONG);
- }});
-
- 0x2: ceil_l_s({{
- Fd.ud = fpConvert(ceil(Fs.sf), SINGLE_TO_LONG);
- }});
-
- 0x3: floor_l_s({{
- Fd.ud = fpConvert(floor(Fs.sf), SINGLE_TO_LONG);
- }});
- }
-
- format FloatOp {
- 0x4: round_w_s({{
- Fd.uw = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_WORD);
- }});
-
- 0x5: trunc_w_s({{
- Fd.uw = fpConvert(truncFP(Fs.sf), SINGLE_TO_WORD);
- }});
-
- 0x6: ceil_w_s({{
- Fd.uw = fpConvert(ceil(Fs.sf), SINGLE_TO_WORD);
- }});
-
- 0x7: floor_w_s({{
- Fd.uw = fpConvert(floor(Fs.sf), SINGLE_TO_WORD);
- }});
+ format FloatConvertOp {
+ 0x0: round_l_s({{ val = Fs.sf; }}, ToLong,
+ Round);
+ 0x1: trunc_l_s({{ val = Fs.sf; }}, ToLong,
+ Trunc);
+ 0x2: ceil_l_s({{ val = Fs.sf; }}, ToLong,
+ Ceil);
+ 0x3: floor_l_s({{ val = Fs.sf; }}, ToLong,
+ Floor);
+ 0x4: round_w_s({{ val = Fs.sf; }}, ToWord,
+ Round);
+ 0x5: trunc_w_s({{ val = Fs.sf; }}, ToWord,
+ Trunc);
+ 0x6: ceil_w_s({{ val = Fs.sf; }}, ToWord,
+ Ceil);
+ 0x7: floor_w_s({{ val = Fs.sf; }}, ToWord,
+ Floor);
}
}
0x2: decode FUNCTION_LO {
0x1: decode MOVCF {
- format FloatOp {
- 0x0: movf_s({{if (getFPConditionCode(FCSR,CC) == 0) Fd = Fs;}});
- 0x1: movt_s({{if (getFPConditionCode(FCSR,CC) == 1) Fd = Fs;}});
+ format BasicOp {
+ 0x0: movf_s({{ Fd = (getCondCode(FCSR,CC) == 0) ? Fs : Fd; }});
+ 0x1: movt_s({{ Fd = (getCondCode(FCSR,CC) == 1) ? Fs : Fd; }});
}
}
+ format BasicOp {
+ 0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }});
+ 0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }});
+ }
+
format FloatOp {
- 0x2: movz_s({{ if (Rt == 0) Fd = Fs; }});
- 0x3: movn_s({{ if (Rt != 0) Fd = Fs; }});
0x5: recip_s({{ Fd = 1 / Fs; }});
0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs);}});
}
}
0x4: decode FUNCTION_LO {
-
format FloatConvertOp {
- 0x1: cvt_d_s({{
- Fd.ud = fpConvert(Fs.sf, SINGLE_TO_DOUBLE);
- }});
-
- 0x4: cvt_w_s({{
- Fd.uw = fpConvert(Fs.sf, SINGLE_TO_WORD);
- }});
+ 0x1: cvt_d_s({{ val = Fs.sf; }}, ToDouble);
+ 0x4: cvt_w_s({{ val = Fs.sf; }}, ToWord);
+ 0x5: cvt_l_s({{ val = Fs.sf; }}, ToLong);
}
- format FloatConvertOp {
- 0x5: cvt_l_s({{
- Fd.ud = fpConvert(Fs.sf, SINGLE_TO_LONG);
+ 0x6: FloatOp::cvt_ps_s({{
+ Fd.ud = (uint64_t) Fs.uw << 32 |
+ (uint64_t) Ft.uw;
}});
-
- 0x6: cvt_ps_st({{
- Fd.ud = (uint64_t)Fs.uw << 32 | (uint64_t)Ft.uw;
- }});
- }
}
0x6: decode FUNCTION_LO {
format FloatCompareOp {
- 0x0: c_f_s({{ cond = 0; }});
-
- 0x1: c_un_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 1;
- else
- cond = 0;
- }});
-
- 0x2: c_eq_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 0;
- else
- cond = (Fs.sf == Ft.sf);
- }});
-
- 0x3: c_ueq_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 1;
- else
- cond = (Fs.sf == Ft.sf);
- }});
-
- 0x4: c_olt_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 0;
- else
- cond = (Fs.sf < Ft.sf);
- }});
-
- 0x5: c_ult_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 1;
- else
- cond = (Fs.sf < Ft.sf);
- }});
-
- 0x6: c_ole_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 0;
- else
- cond = (Fs.sf <= Ft.sf);
- }});
-
- 0x7: c_ule_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 1;
- else
- cond = (Fs.sf <= Ft.sf);
- }});
+ 0x0: c_f_s({{ cond = 0; }}, SinglePrecision,
+ UnorderedFalse);
+ 0x1: c_un_s({{ cond = 0; }}, SinglePrecision,
+ UnorderedTrue);
+ 0x2: c_eq_s({{ cond = (Fs.sf == Ft.sf); }},
+ UnorderedFalse);
+ 0x3: c_ueq_s({{ cond = (Fs.sf == Ft.sf); }},
+ UnorderedTrue);
+ 0x4: c_olt_s({{ cond = (Fs.sf < Ft.sf); }},
+ UnorderedFalse);
+ 0x5: c_ult_s({{ cond = (Fs.sf < Ft.sf); }},
+ UnorderedTrue);
+ 0x6: c_ole_s({{ cond = (Fs.sf <= Ft.sf); }},
+ UnorderedFalse);
+ 0x7: c_ule_s({{ cond = (Fs.sf <= Ft.sf); }},
+ UnorderedTrue);
}
}
0x7: decode FUNCTION_LO {
- format FloatCompareWithXcptOp {
- 0x0: c_sf_s({{ cond = 0; }});
-
- 0x1: c_ngle_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 1;
- else
- cond = 0;
- }});
-
- 0x2: c_seq_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 0;
- else
- cond = (Fs.sf == Ft.sf);
- }});
-
- 0x3: c_ngl_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 1;
- else
- cond = (Fs.sf == Ft.sf);
- }});
-
- 0x4: c_lt_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 0;
- else
- cond = (Fs.sf < Ft.sf);
- }});
-
- 0x5: c_nge_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 1;
- else
- cond = (Fs.sf < Ft.sf);
- }});
-
- 0x6: c_le_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 0;
- else
- cond = (Fs.sf <= Ft.sf);
- }});
-
- 0x7: c_ngt_s({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond = 1;
- else
- cond = (Fs.sf <= Ft.sf);
- }});
+ format FloatCompareOp {
+ 0x0: c_sf_s({{ cond = 0; }}, SinglePrecision,
+ UnorderedFalse, QnanException);
+ 0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision,
+ UnorderedTrue, QnanException);
+ 0x2: c_seq_s({{ cond = (Fs.sf == Ft.sf);}},
+ UnorderedFalse, QnanException);
+ 0x3: c_ngl_s({{ cond = (Fs.sf == Ft.sf); }},
+ UnorderedTrue, QnanException);
+ 0x4: c_lt_s({{ cond = (Fs.sf < Ft.sf); }},
+ UnorderedFalse, QnanException);
+ 0x5: c_nge_s({{ cond = (Fs.sf < Ft.sf); }},
+ UnorderedTrue, QnanException);
+ 0x6: c_le_s({{ cond = (Fs.sf <= Ft.sf); }},
+ UnorderedFalse, QnanException);
+ 0x7: c_ngt_s({{ cond = (Fs.sf <= Ft.sf); }},
+ UnorderedTrue, QnanException);
}
}
}
@@ -695,197 +543,108 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode FUNCTION_HI {
0x0: decode FUNCTION_LO {
format FloatOp {
- 0x0: add_d({{ Fd.df = Fs.df + Ft.df;}});
- 0x1: sub_d({{ Fd.df = Fs.df - Ft.df;}});
- 0x2: mul_d({{ Fd.df = Fs.df * Ft.df;}});
- 0x3: div_d({{ Fd.df = Fs.df / Ft.df;}});
- 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df);}});
- 0x5: abs_d({{ Fd.df = fabs(Fs.df);}});
- 0x6: mov_d({{ Fd.ud = Fs.ud;}});
- 0x7: neg_d({{ Fd.df = -1 * Fs.df;}});
+ 0x0: add_d({{ Fd.df = Fs.df + Ft.df; }});
+ 0x1: sub_d({{ Fd.df = Fs.df - Ft.df; }});
+ 0x2: mul_d({{ Fd.df = Fs.df * Ft.df; }});
+ 0x3: div_d({{ Fd.df = Fs.df / Ft.df; }});
+ 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df); }});
+ 0x5: abs_d({{ Fd.df = fabs(Fs.df); }});
+ 0x6: mov_d({{ Fd.df = Fs.df; }});
+ 0x7: neg_d({{ Fd.df = -1 * Fs.df; }});
}
}
0x1: decode FUNCTION_LO {
- format FloatOp {
- 0x0: round_l_d({{
- Fd.ud = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_LONG);
- }});
-
- 0x1: trunc_l_d({{
- Fd.ud = fpConvert(truncFP(Fs.df), DOUBLE_TO_LONG);
- }});
-
- 0x2: ceil_l_d({{
- Fd.ud = fpConvert(ceil(Fs.df), DOUBLE_TO_LONG);
- }});
-
- 0x3: floor_l_d({{
- Fd.ud = fpConvert(floor(Fs.df), DOUBLE_TO_LONG);
- }});
- }
-
- format FloatOp {
- 0x4: round_w_d({{
- Fd.uw = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_WORD);
- }});
-
- 0x5: trunc_w_d({{
- Fd.uw = fpConvert(truncFP(Fs.df), DOUBLE_TO_WORD);
- }});
-
- 0x6: ceil_w_d({{
- Fd.uw = fpConvert(ceil(Fs.df), DOUBLE_TO_WORD);
- }});
-
- 0x7: floor_w_d({{
- Fd.uw = fpConvert(floor(Fs.df), DOUBLE_TO_WORD);
- }});
+ format FloatConvertOp {
+ 0x0: round_l_d({{ val = Fs.df; }}, ToLong,
+ Round);
+ 0x1: trunc_l_d({{ val = Fs.df; }}, ToLong,
+ Trunc);
+ 0x2: ceil_l_d({{ val = Fs.df; }}, ToLong,
+ Ceil);
+ 0x3: floor_l_d({{ val = Fs.df; }}, ToLong,
+ Floor);
+ 0x4: round_w_d({{ val = Fs.df; }}, ToWord,
+ Round);
+ 0x5: trunc_w_d({{ val = Fs.df; }}, ToWord,
+ Trunc);
+ 0x6: ceil_w_d({{ val = Fs.df; }}, ToWord,
+ Ceil);
+ 0x7: floor_w_d({{ val = Fs.df; }}, ToWord,
+ Floor);
}
}
0x2: decode FUNCTION_LO {
0x1: decode MOVCF {
- format FloatOp {
- 0x0: movf_d({{if (getFPConditionCode(FCSR,CC) == 0) Fd.df = Fs.df; }});
- 0x1: movt_d({{if (getFPConditionCode(FCSR,CC) == 1) Fd.df = Fs.df; }});
+ format BasicOp {
+ 0x0: movf_d({{ Fd.df = (getCondCode(FCSR,CC) == 0) ?
+ Fs.df : Fd.df;
+ }});
+ 0x1: movt_d({{ Fd.df = (getCondCode(FCSR,CC) == 1) ?
+ Fs.df : Fd.df;
+ }});
}
}
format BasicOp {
- 0x2: movz_d({{ if (Rt == 0) Fd.df = Fs.df; }});
- 0x3: movn_d({{ if (Rt != 0) Fd.df = Fs.df; }});
+ 0x2: movz_d({{ Fd.df = (Rt == 0) ? Fs.df : Fd.df; }});
+ 0x3: movn_d({{ Fd.df = (Rt != 0) ? Fs.df : Fd.df; }});
}
format FloatOp {
- 0x5: recip_d({{ Fd.df = 1 / Fs.df}});
+ 0x5: recip_d({{ Fd.df = 1 / Fs.df }});
0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df) }});
}
}
0x4: decode FUNCTION_LO {
- format FloatOp {
- 0x0: cvt_s_d({{
- Fd.uw = fpConvert(Fs.df, DOUBLE_TO_SINGLE);
- }});
-
- 0x4: cvt_w_d({{
- Fd.uw = fpConvert(Fs.df, DOUBLE_TO_WORD);
- }});
-
- 0x5: cvt_l_d({{
- Fd.ud = fpConvert(Fs.df, DOUBLE_TO_LONG);
- }});
+ format FloatConvertOp {
+ 0x0: cvt_s_d({{ val = Fs.df; }}, ToSingle);
+ 0x4: cvt_w_d({{ val = Fs.df; }}, ToWord);
+ 0x5: cvt_l_d({{ val = Fs.df; }}, ToLong);
}
}
0x6: decode FUNCTION_LO {
format FloatCompareOp {
- 0x0: c_f_d({{ cond = 0; }});
-
- 0x1: c_un_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 1;
- else
- cond = 0;
- }});
-
- 0x2: c_eq_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 0;
- else
- cond = (Fs.df == Ft.df);
- }});
-
- 0x3: c_ueq_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 1;
- else
- cond = (Fs.df == Ft.df);
- }});
-
- 0x4: c_olt_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 0;
- else
- cond = (Fs.df < Ft.df);
- }});
-
- 0x5: c_ult_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 1;
- else
- cond = (Fs.df < Ft.df);
- }});
-
- 0x6: c_ole_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 0;
- else
- cond = (Fs.df <= Ft.df);
- }});
-
- 0x7: c_ule_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 1;
- else
- cond = (Fs.df <= Ft.df);
- }});
+ 0x0: c_f_d({{ cond = 0; }}, DoublePrecision,
+ UnorderedFalse);
+ 0x1: c_un_d({{ cond = 0; }}, DoublePrecision,
+ UnorderedTrue);
+ 0x2: c_eq_d({{ cond = (Fs.df == Ft.df); }},
+ UnorderedFalse);
+ 0x3: c_ueq_d({{ cond = (Fs.df == Ft.df); }},
+ UnorderedTrue);
+ 0x4: c_olt_d({{ cond = (Fs.df < Ft.df); }},
+ UnorderedFalse);
+ 0x5: c_ult_d({{ cond = (Fs.df < Ft.df); }},
+ UnorderedTrue);
+ 0x6: c_ole_d({{ cond = (Fs.df <= Ft.df); }},
+ UnorderedFalse);
+ 0x7: c_ule_d({{ cond = (Fs.df <= Ft.df); }},
+ UnorderedTrue);
}
}
0x7: decode FUNCTION_LO {
- format FloatCompareWithXcptOp {
- 0x0: c_sf_d({{ cond = 0; }});
-
- 0x1: c_ngle_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 1;
- else
- cond = 0;
- }});
-
- 0x2: c_seq_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 0;
- else
- cond = (Fs.df == Ft.df);
- }});
-
- 0x3: c_ngl_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 1;
- else
- cond = (Fs.df == Ft.df);
- }});
-
- 0x4: c_lt_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 0;
- else
- cond = (Fs.df < Ft.df);
- }});
-
- 0x5: c_nge_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 1;
- else
- cond = (Fs.df < Ft.df);
- }});
-
- 0x6: c_le_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 0;
- else
- cond = (Fs.df <= Ft.df);
- }});
-
- 0x7: c_ngt_d({{
- if (isnan(Fs.df) || isnan(Ft.df))
- cond = 1;
- else
- cond = (Fs.df <= Ft.df);
- }});
+ format FloatCompareOp {
+ 0x0: c_sf_d({{ cond = 0; }}, DoublePrecision,
+ UnorderedFalse, QnanException);
+ 0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision,
+ UnorderedTrue, QnanException);
+ 0x2: c_seq_d({{ cond = (Fs.df == Ft.df); }},
+ UnorderedFalse, QnanException);
+ 0x3: c_ngl_d({{ cond = (Fs.df == Ft.df); }},
+ UnorderedTrue, QnanException);
+ 0x4: c_lt_d({{ cond = (Fs.df < Ft.df); }},
+ UnorderedFalse, QnanException);
+ 0x5: c_nge_d({{ cond = (Fs.df < Ft.df); }},
+ UnorderedTrue, QnanException);
+ 0x6: c_le_d({{ cond = (Fs.df <= Ft.df); }},
+ UnorderedFalse, QnanException);
+ 0x7: c_ngt_d({{ cond = (Fs.df <= Ft.df); }},
+ UnorderedTrue, QnanException);
}
}
}
@@ -893,19 +652,9 @@ decode OPCODE_HI default Unknown::unknown() {
//Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
0x4: decode FUNCTION {
format FloatConvertOp {
- 0x20: cvt_s_w({{
- Fd.uw = fpConvert(Fs.sf, WORD_TO_SINGLE);
- }});
-
- 0x21: cvt_d_w({{
- Fd.ud = fpConvert(Fs.sf, WORD_TO_DOUBLE);
- }});
- }
-
- format Float64ConvertOp {
- 0x26: cvt_ps_pw({{
- Fd.ud = fpConvert(Fs.ud, WORD_TO_PS);
- }});
+ 0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle);
+ 0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble);
+ 0x26: FailUnimpl::cvt_ps_w();
}
}
@@ -913,18 +662,10 @@ decode OPCODE_HI default Unknown::unknown() {
//Note: "1. Format type L is legal only if 64-bit floating point operations
//are enabled."
0x5: decode FUNCTION_HI {
- format Float64ConvertOp {
- 0x20: cvt_s_l({{
- Fd.uw = fpConvert(Fs.ud, LONG_TO_SINGLE);
- }});
-
- 0x21: cvt_d_l({{
- Fd.ud = fpConvert(Fs.ud, LONG_TO_DOUBLE);
- }});
-
- 0x26: cvt_ps_l({{
- Fd.ud = fpConvert(Fs.ud, LONG_TO_PS);
- }});
+ format FloatConvertOp {
+ 0x20: cvt_s_l({{ val = Fs.ud; }}, ToSingle);
+ 0x21: cvt_d_l({{ val = Fs.ud; }}, ToDouble);
+ 0x26: FailUnimpl::cvt_ps_l();
}
}
@@ -938,30 +679,25 @@ decode OPCODE_HI default Unknown::unknown() {
Fd1.sf = Fs1.sf + Ft2.sf;
Fd2.sf = Fs2.sf + Ft2.sf;
}});
-
0x1: sub_ps({{
Fd1.sf = Fs1.sf - Ft2.sf;
Fd2.sf = Fs2.sf - Ft2.sf;
}});
-
0x2: mul_ps({{
Fd1.sf = Fs1.sf * Ft2.sf;
Fd2.sf = Fs2.sf * Ft2.sf;
}});
-
0x5: abs_ps({{
Fd1.sf = fabs(Fs1.sf);
Fd2.sf = fabs(Fs2.sf);
}});
-
0x6: mov_ps({{
Fd1.sf = Fs1.sf;
Fd2.sf = Fs2.sf;
}});
-
0x7: neg_ps({{
- Fd1.sf = -1 * Fs1.sf;
- Fd2.sf = -1 * Fs2.sf;
+ Fd1.sf = -(Fs1.sf);
+ Fd2.sf = -(Fs2.sf);
}});
}
}
@@ -970,236 +706,112 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode MOVCF {
format Float64Op {
0x0: movf_ps({{
- if (getFPConditionCode(FCSR, CC) == 0)
- Fd1 = Fs1;
- if (getFPConditionCode(FCSR, CC+1) == 0)
- Fd2 = Fs2;
+ Fd1 = (getCondCode(FCSR, CC) == 0) ?
+ Fs1 : Fd1;
+ Fd2 = (getCondCode(FCSR, CC+1) == 0) ?
+ Fs2 : Fd2;
}});
-
0x1: movt_ps({{
- if (getFPConditionCode(FCSR, CC) == 1)
- Fd1 = Fs1;
- if (getFPConditionCode(FCSR, CC+1) == 1)
- Fd2 = Fs2;
+ Fd2 = (getCondCode(FCSR, CC) == 1) ?
+ Fs1 : Fd1;
+ Fd2 = (getCondCode(FCSR, CC+1) == 1) ?
+ Fs2 : Fd2;
}});
}
}
format Float64Op {
0x2: movz_ps({{
- if (getFPConditionCode(FCSR, CC) == 0)
- Fd1 = Fs1;
- if (getFPConditionCode(FCSR, CC) == 0)
- Fd2 = Fs2;
+ Fd1 = (getCondCode(FCSR, CC) == 0) ?
+ Fs1 : Fd1;
+ Fd2 = (getCondCode(FCSR, CC) == 0) ?
+ Fs2 : Fd2;
}});
-
0x3: movn_ps({{
- if (getFPConditionCode(FCSR, CC) == 1)
- Fd1 = Fs1;
- if (getFPConditionCode(FCSR, CC) == 1)
- Fd2 = Fs2;
+ Fd1 = (getCondCode(FCSR, CC) == 1) ?
+ Fs1 : Fd1;
+ Fd2 = (getCondCode(FCSR, CC) == 1) ?
+ Fs2 : Fd2;
}});
}
}
0x4: decode FUNCTION_LO {
- 0x0: Float64Op::cvt_s_pu({{
- Fd.uw = fpConvert(Fs2.uw, PU_TO_SINGLE);
- }});
+ 0x0: FloatOp::cvt_s_pu({{ Fd.sf = Fs2.sf; }});
}
0x5: decode FUNCTION_LO {
- format Float64Op {
- 0x0: cvt_s_pl({{
- Fd.uw = fpConvert(Fs1.uw, PL_TO_SINGLE);
- }});
+ 0x0: FloatOp::cvt_s_pl({{ Fd.sf = Fs1.sf; }});
- 0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft1.uw; }});
- 0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft2.uw; }});
- 0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft1.uw; }});
- 0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft2.uw; }});
+ format Float64Op {
+ 0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 |
+ Ft1.uw;
+ }});
+ 0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 |
+ Ft2.uw;
+ }});
+ 0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 |
+ Ft1.uw;
+ }});
+ 0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 |
+ Ft2.uw;
+ }});
}
}
0x6: decode FUNCTION_LO {
format FloatPSCompareOp {
- 0x0: c_f_ps({{ cond1 = 0; cond2 = 0; }});
-
- 0x1: c_un_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 1;
- else
- cond1 = 0;
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 1;
- else
- cond2 = 0;
-
- }});
-
- 0x2: c_eq_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 0;
- else
- cond1 = (Fs1.sf == Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 0;
- else
- cond2 = (Fs2.sf == Ft2.sf);
- }});
-
- 0x3: c_ueq_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 1;
- else
- cond1 = (Fs1.sf == Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 1;
- else
- cond2 = (Fs2.sf == Ft2.sf);
- }});
-
- 0x4: c_olt_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 0;
- else
- cond1 = (Fs1.sf < Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 0;
- else
- cond2 = (Fs2.sf < Ft2.sf);
- }});
-
- 0x5: c_ult_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 1;
- else
- cond1 = (Fs.sf < Ft.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 1;
- else
- cond2 = (Fs2.sf < Ft2.sf);
- }});
-
- 0x6: c_ole_ps({{
- if (isnan(Fs.sf) || isnan(Ft.sf))
- cond1 = 0;
- else
- cond1 = (Fs.sf <= Ft.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 0;
- else
- cond2 = (Fs2.sf <= Ft2.sf);
- }});
-
- 0x7: c_ule_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 1;
- else
- cond1 = (Fs1.sf <= Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 1;
- else
- cond2 = (Fs2.sf <= Ft2.sf);
- }});
+ 0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
+ UnorderedFalse);
+ 0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
+ UnorderedTrue);
+ 0x2: c_eq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+ {{ cond2 = (Fs2.sf == Ft2.sf); }},
+ UnorderedFalse);
+ 0x3: c_ueq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+ {{ cond2 = (Fs2.sf == Ft2.sf); }},
+ UnorderedTrue);
+ 0x4: c_olt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
+ {{ cond2 = (Fs2.sf < Ft2.sf); }},
+ UnorderedFalse);
+ 0x5: c_ult_ps({{ cond1 = (Fs.sf < Ft.sf); }},
+ {{ cond2 = (Fs2.sf < Ft2.sf); }},
+ UnorderedTrue);
+ 0x6: c_ole_ps({{ cond1 = (Fs.sf <= Ft.sf); }},
+ {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+ UnorderedFalse);
+ 0x7: c_ule_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
+ {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+ UnorderedTrue);
}
}
0x7: decode FUNCTION_LO {
- format FloatPSCompareWithXcptOp {
- 0x0: c_sf_ps({{ cond1 = 0; cond2 = 0; }});
-
- 0x1: c_ngle_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 1;
- else
- cond1 = 0;
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 1;
- else
- cond2 = 0;
- }});
-
- 0x2: c_seq_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 0;
- else
- cond1 = (Fs1.sf == Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 0;
- else
- cond2 = (Fs2.sf == Ft2.sf);
- }});
-
- 0x3: c_ngl_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 1;
- else
- cond1 = (Fs1.sf == Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 1;
- else
- cond2 = (Fs2.sf == Ft2.sf);
- }});
-
- 0x4: c_lt_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 0;
- else
- cond1 = (Fs1.sf < Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 0;
- else
- cond2 = (Fs2.sf < Ft2.sf);
- }});
-
- 0x5: c_nge_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 1;
- else
- cond1 = (Fs1.sf < Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 1;
- else
- cond2 = (Fs2.sf < Ft2.sf);
- }});
-
- 0x6: c_le_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 0;
- else
- cond1 = (Fs1.sf <= Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 0;
- else
- cond2 = (Fs2.sf <= Ft2.sf);
- }});
-
- 0x7: c_ngt_ps({{
- if (isnan(Fs1.sf) || isnan(Ft1.sf))
- cond1 = 1;
- else
- cond1 = (Fs1.sf <= Ft1.sf);
-
- if (isnan(Fs2.sf) || isnan(Ft2.sf))
- cond2 = 1;
- else
- cond2 = (Fs2.sf <= Ft2.sf);
- }});
+ format FloatPSCompareOp {
+ 0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
+ UnorderedFalse, QnanException);
+ 0x1: c_ngle_ps({{ cond1 = 0; }},
+ {{ cond2 = 0; }},
+ UnorderedTrue, QnanException);
+ 0x2: c_seq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+ {{ cond2 = (Fs2.sf == Ft2.sf); }},
+ UnorderedFalse, QnanException);
+ 0x3: c_ngl_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+ {{ cond2 = (Fs2.sf == Ft2.sf); }},
+ UnorderedTrue, QnanException);
+ 0x4: c_lt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
+ {{ cond2 = (Fs2.sf < Ft2.sf); }},
+ UnorderedFalse, QnanException);
+ 0x5: c_nge_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
+ {{ cond2 = (Fs2.sf < Ft2.sf); }},
+ UnorderedTrue, QnanException);
+ 0x6: c_le_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
+ {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+ UnorderedFalse, QnanException);
+ 0x7: c_ngt_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
+ {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+ UnorderedTrue, QnanException);
}
}
}
@@ -1209,9 +821,9 @@ decode OPCODE_HI default Unknown::unknown() {
//Table A-19 MIPS32 COP2 Encoding of rs Field
0x2: decode RS_MSB {
- 0x0: decode RS_HI {
- 0x0: decode RS_LO {
- format WarnUnimpl {
+ format FailUnimpl {
+ 0x0: decode RS_HI {
+ 0x0: decode RS_LO {
0x0: mfc2();
0x2: cfc2();
0x3: mfhc2();
@@ -1219,18 +831,14 @@ decode OPCODE_HI default Unknown::unknown() {
0x6: ctc2();
0x7: mftc2();
}
- }
- 0x1: decode ND {
- 0x0: decode TF {
- format WarnUnimpl {
+ 0x1: decode ND {
+ 0x0: decode TF {
0x0: bc2f();
0x1: bc2t();
}
- }
- 0x1: decode TF {
- format WarnUnimpl {
+ 0x1: decode TF {
0x0: bc2fl();
0x1: bc2tl();
}
@@ -1244,441 +852,240 @@ decode OPCODE_HI default Unknown::unknown() {
//operations are enabled."
0x3: decode FUNCTION_HI {
0x0: decode FUNCTION_LO {
- format LoadFloatMemory {
- 0x0: lwxc1({{ Ft.uw = Mem.uw;}}, {{ EA = Rs + Rt; }});
- 0x1: ldxc1({{ Ft.ud = Mem.ud;}}, {{ EA = Rs + Rt; }});
- 0x5: luxc1({{ Ft.uw = Mem.ud;}}, {{ EA = Rs + Rt; }});
+ format LoadIndexedMemory {
+ 0x0: lwxc1({{ Ft.uw = Mem.uw;}});
+ 0x1: ldxc1({{ Ft.ud = Mem.ud;}});
+ 0x5: luxc1({{ Ft.uw = Mem.ud;}});
}
}
0x1: decode FUNCTION_LO {
- format StoreFloatMemory {
- 0x0: swxc1({{ Mem.uw = Ft.uw;}}, {{ EA = Rs + Rt; }});
- 0x1: sdxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }});
- 0x5: suxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }});
+ format StoreIndexedMemory {
+ 0x0: swxc1({{ Mem.uw = Ft.uw;}});
+ 0x1: sdxc1({{ Mem.ud = Ft.ud;}});
+ 0x5: suxc1({{ Mem.ud = Ft.ud;}});
}
- 0x7: WarnUnimpl::prefx();
+ 0x7: Prefetch::prefx({{ EA = Rs + Rt; }});
}
- format FloatOp {
- 0x3: WarnUnimpl::alnv_ps();
+ 0x3: decode FUNCTION_LO {
+ 0x6: Float64Op::alnv_ps({{ if (Rs<2:0> == 0) {
+ Fd.ud = Fs.ud;
+ } else if (Rs<2:0> == 4) {
+ #if BYTE_ORDER == BIG_ENDIAN
+ Fd.ud = Fs.ud<31:0> << 32 |
+ Ft.ud<63:32>;
+ #elif BYTE_ORDER == LITTLE_ENDIAN
+ Fd.ud = Ft.ud<31:0> << 32 |
+ Fs.ud<63:32>;
+ #endif
+ } else {
+ Fd.ud = Fd.ud;
+ }
+ }});
+ }
- format BasicOp {
- 0x4: decode FUNCTION_LO {
- 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }});
- 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }});
- 0x6: madd_ps({{
- Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df;
- Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df;
- }});
- }
+ format FloatAccOp {
+ 0x4: decode FUNCTION_LO {
+ 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }});
+ 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }});
+ 0x6: madd_ps({{
+ Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df;
+ Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df;
+ }});
+ }
- 0x5: decode FUNCTION_LO {
- 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }});
- 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }});
- 0x6: msub_ps({{
- Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df;
- Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df;
- }});
- }
+ 0x5: decode FUNCTION_LO {
+ 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }});
+ 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }});
+ 0x6: msub_ps({{
+ Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df;
+ Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df;
+ }});
+ }
- 0x6: decode FUNCTION_LO {
- 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
- 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }});
- 0x6: nmadd_ps({{
- Fd1.sf = -1 * ((Fs1.df * Ft1.df) + Fr1.df);
- Fd2.sf = -1 * ((Fs2.df * Ft2.df) + Fr2.df);
- }});
- }
+ 0x6: decode FUNCTION_LO {
+ 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
+ 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }});
+ 0x6: nmadd_ps({{
+ Fd1.sf = -((Fs1.df * Ft1.df) + Fr1.df);
+ Fd2.sf = -((Fs2.df * Ft2.df) + Fr2.df);
+ }});
+ }
- 0x7: decode FUNCTION_LO {
- 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
- 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }});
- 0x6: nmsub_ps({{
- Fd1.sf = -1 * ((Fs1.df * Ft1.df) - Fr1.df);
- Fd2.sf = -1 * ((Fs2.df * Ft2.df) - Fr2.df);
- }});
- }
+ 0x7: decode FUNCTION_LO {
+ 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
+ 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }});
+ 0x6: nmsub_ps({{
+ Fd1.sf = -((Fs1.df * Ft1.df) - Fr1.df);
+ Fd2.sf = -((Fs2.df * Ft2.df) - Fr2.df);
+ }});
}
+
}
}
- format BranchLikely {
- 0x4: beql({{ cond = (Rs.sw == 0); }});
- 0x5: bnel({{ cond = (Rs.sw != 0); }});
- 0x6: blezl({{ cond = (Rs.sw <= 0); }});
- 0x7: bgtzl({{ cond = (Rs.sw > 0); }});
+ format Branch {
+ 0x4: beql({{ cond = (Rs.sw == Rt.sw); }}, Likely);
+ 0x5: bnel({{ cond = (Rs.sw != Rt.sw); }}, Likely);
+ 0x6: blezl({{ cond = (Rs.sw <= 0); }}, Likely);
+ 0x7: bgtzl({{ cond = (Rs.sw > 0); }}, Likely);
}
}
- 0x3: decode OPCODE_LO default FailUnimpl::reserved() {
-
+ 0x3: decode OPCODE_LO {
//Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
0x4: decode FUNCTION_HI {
-
0x0: decode FUNCTION_LO {
- format IntOp {
- 0x0: madd({{
- int64_t temp1 = (int64_t) HI << 32 | LO;
- temp1 = temp1 + (Rs.sw * Rt.sw);
- HI = temp1<63:32>;
- LO = temp1<31:0>;
- }});
-
- 0x1: maddu({{
- int64_t temp1 = (int64_t) HI << 32 | LO;
- temp1 = temp1 + (Rs.uw * Rt.uw);
- HI = temp1<63:32>;
- LO = temp1<31:0>;
- }});
-
- 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }});
-
- 0x4: msub({{
- int64_t temp1 = (int64_t) HI << 32 | LO;
- temp1 = temp1 - (Rs.sw * Rt.sw);
- HI = temp1<63:32>;
- LO = temp1<31:0>;
- }});
+ 0x2: IntOp::mul({{ int64_t temp1 = Rs.sd * Rt.sd;
+ Rd.sw = temp1<31:0>
+ }});
- 0x5: msubu({{
- int64_t temp1 = (int64_t) HI << 32 | LO;
- temp1 = temp1 - (Rs.uw * Rt.uw);
- HI = temp1<63:32>;
- LO = temp1<31:0>;
- }});
+ format HiLoOp {
+ 0x0: madd({{ val = ((int64_t) HI << 32 | LO) +
+ (Rs.sd * Rt.sd);
+ }});
+ 0x1: maddu({{ val = ((uint64_t) HI << 32 | LO) +
+ (Rs.ud * Rt.ud);
+ }});
+ 0x4: msub({{ val = ((int64_t) HI << 32 | LO) -
+ (Rs.sd * Rt.sd);
+ }});
+ 0x5: msubu({{ val = ((uint64_t) HI << 32 | LO) -
+ (Rs.ud * Rt.ud);
+ }});
}
}
0x4: decode FUNCTION_LO {
format BasicOp {
- 0x0: clz({{
- int cnt = 0;
- uint32_t mask = 0x80000000;
- for (int i=0; i < 32; i++) {
- if( (Rs & mask) == 0) {
- cnt++;
- } else {
- break;
- }
- }
- Rd.uw = cnt;
- }});
-
- 0x1: clo({{
- int cnt = 0;
- uint32_t mask = 0x80000000;
- for (int i=0; i < 32; i++) {
- if( (Rs & mask) != 0) {
- cnt++;
- } else {
- break;
- }
- }
- Rd.uw = cnt;
- }});
+ 0x0: clz({{ int cnt = 32;
+ for (int idx = 31; idx >= 0; idx--) {
+ if( Rs<idx:idx> == 1) {
+ cnt = 31 - idx;
+ break;
+ }
+ }
+ Rd.uw = cnt;
+ }});
+ 0x1: clo({{ int cnt = 32;
+ for (int idx = 31; idx >= 0; idx--) {
+ if( Rs<idx:idx> == 0) {
+ cnt = 31 - idx;
+ break;
+ }
+ }
+ Rd.uw = cnt;
+ }});
}
}
0x7: decode FUNCTION_LO {
- 0x7: WarnUnimpl::sdbbp();
+ 0x7: FailUnimpl::sdbbp();
}
}
- //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
+ //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2
+ //of the Architecture
0x7: decode FUNCTION_HI {
-
0x0: decode FUNCTION_LO {
- format FailUnimpl {
- 0x1: ext();
- 0x4: ins();
+ format BasicOp {
+ 0x1: ext({{ Rt.uw = bits(Rs.uw, MSB+LSB, LSB); }});
+ 0x4: ins({{ Rt.uw = bits(Rt.uw, 31, MSB+1) << (MSB+1) |
+ bits(Rs.uw, MSB-LSB, 0) << LSB |
+ bits(Rt.uw, LSB-1, 0);
+ }});
}
}
0x1: decode FUNCTION_LO {
- format FailUnimpl {
+ format MipsMT {
0x0: fork();
0x1: yield();
}
}
-
//Table A-10 MIPS32 BSHFL Encoding of sa Field
0x4: decode SA {
-
- 0x02: FailUnimpl::wsbh();
-
format BasicOp {
+ 0x02: wsbh({{ Rd.uw = Rt.uw<23:16> << 24 |
+ Rt.uw<31:24> << 16 |
+ Rt.uw<7:0> << 8 |
+ Rt.uw<15:8>;
+ }});
0x10: seb({{ Rd.sw = Rt.sw<7:0>}});
0x18: seh({{ Rd.sw = Rt.sw<15:0>}});
}
}
0x6: decode FUNCTION_LO {
- 0x7: FailUnimpl::rdhwr();//{{ /*Rt = xc->hwRegs[RD];*/ }}
+ 0x7: FailUnimpl::rdhwr();
}
}
}
- 0x4: decode OPCODE_LO default FailUnimpl::reserved() {
+ 0x4: decode OPCODE_LO {
format LoadMemory {
0x0: lb({{ Rt.sw = Mem.sb; }});
0x1: lh({{ Rt.sw = Mem.sh; }});
-
- 0x2: lwl({{
- uint32_t mem_word = Mem.uw;
- uint32_t unalign_addr = Rs + disp;
- uint32_t offset = unalign_addr & 0x00000003;
-#if BYTE_ORDER == BIG_ENDIAN
- switch(offset)
- {
- case 0:
- Rt = mem_word;
- break;
-
- case 1:
- Rt &= 0x000F;
- Rt |= (mem_word << 4);
- break;
-
- case 2:
- Rt &= 0x00FF;
- Rt |= (mem_word << 8);
- break;
-
- case 3:
- Rt &= 0x0FFF;
- Rt |= (mem_word << 12);
- break;
-
- default:
- panic("lwl: bad offset");
- }
-#elif BYTE_ORDER == LITTLE_ENDIAN
- switch(offset)
- {
- case 0:
- Rt &= 0x0FFF;
- Rt |= (mem_word << 12);
- break;
-
- case 1:
- Rt &= 0x00FF;
- Rt |= (mem_word << 8);
- break;
-
- case 2:
- Rt &= 0x000F;
- Rt |= (mem_word << 4);
- break;
-
- case 3:
- Rt = mem_word;
- break;
-
- default:
- panic("lwl: bad offset");
- }
-#endif
- }}, {{ EA = (Rs + disp) & ~3; }});
-
0x3: lw({{ Rt.sw = Mem.sw; }});
0x4: lbu({{ Rt.uw = Mem.ub; }});
0x5: lhu({{ Rt.uw = Mem.uh; }});
- 0x6: lwr({{
- uint32_t mem_word = Mem.uw;
- uint32_t unalign_addr = Rs + disp;
- uint32_t offset = unalign_addr & 0x00000003;
-
-#if BYTE_ORDER == BIG_ENDIAN
- switch(offset)
- {
- case 0: Rt &= 0xFFF0; Rt |= (mem_word >> 12); break;
- case 1: Rt &= 0xFF00; Rt |= (mem_word >> 8); break;
- case 2: Rt &= 0xF000; Rt |= (mem_word >> 4); break;
- case 3: Rt = mem_word; break;
- default: panic("lwr: bad offset");
- }
-#elif BYTE_ORDER == LITTLE_ENDIAN
- switch(offset)
- {
- case 0: Rt = mem_word; break;
- case 1: Rt &= 0xF000; Rt |= (mem_word >> 4); break;
- case 2: Rt &= 0xFF00; Rt |= (mem_word >> 8); break;
- case 3: Rt &= 0xFFF0; Rt |= (mem_word >> 12); break;
- default: panic("lwr: bad offset");
- }
-#endif
- }},
- {{ EA = (Rs + disp) & ~3; }});
+ }
+
+ format LoadUnalignedMemory {
+ 0x2: lwl({{ uint32_t mem_shift = 24 - (8 * byte_offset);
+ Rt.uw = mem_word << mem_shift |
+ Rt.uw & mask(mem_shift);
+ }});
+ 0x6: lwr({{ uint32_t mem_shift = 8 * byte_offset;
+ Rt.uw = Rt.uw & (mask(mem_shift) << (32 - mem_shift)) |
+ mem_word >> mem_shift;
+ }});
}
}
- 0x5: decode OPCODE_LO default FailUnimpl::reserved() {
+ 0x5: decode OPCODE_LO {
format StoreMemory {
0x0: sb({{ Mem.ub = Rt<7:0>; }});
0x1: sh({{ Mem.uh = Rt<15:0>; }});
- 0x2: swl({{
- uint32_t mem_word = 0;
- uint32_t aligned_addr = (Rs + disp) & ~3;
- uint32_t unalign_addr = Rs + disp;
- uint32_t offset = unalign_addr & 0x00000003;
-
- DPRINTF(IEW,"Execute: aligned=0x%x unaligned=0x%x\n offset=0x%x",
- aligned_addr,unalign_addr,offset);
-
- fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags);
-
-#if BYTE_ORDER == BIG_ENDIAN
- switch(offset)
- {
- case 0:
- Mem = Rt;
- break;
-
- case 1:
- mem_word &= 0xF000;
- mem_word |= (Rt >> 4);
- Mem = mem_word;
- break;
-
- case 2:
- mem_word &= 0xFF00;
- mem_word |= (Rt >> 8);
- Mem = mem_word;
- break;
-
- case 3:
- mem_word &= 0xFFF0;
- mem_word |= (Rt >> 12);
- Mem = mem_word;
- break;
-
- default:
- panic("swl: bad offset");
- }
-#elif BYTE_ORDER == LITTLE_ENDIAN
- switch(offset)
- {
- case 0:
- mem_word &= 0xFFF0;
- mem_word |= (Rt >> 12);
- Mem = mem_word;
- break;
-
- case 1:
- mem_word &= 0xFF00;
- mem_word |= (Rt >> 8);
- Mem = mem_word;
- break;
-
- case 2:
- mem_word &= 0xF000;
- mem_word |= (Rt >> 4);
- Mem = mem_word;
- break;
-
- case 3:
- Mem = Rt;
- break;
-
- default:
- panic("swl: bad offset");
- }
-#endif
- }},{{ EA = (Rs + disp) & ~3; }},mem_flags = NO_ALIGN_FAULT);
-
0x3: sw({{ Mem.uw = Rt<31:0>; }});
-
- 0x6: swr({{
- uint32_t mem_word = 0;
- uint32_t aligned_addr = (Rs + disp) & ~3;
- uint32_t unalign_addr = Rs + disp;
- uint32_t offset = unalign_addr & 0x00000003;
-
- fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags);
-
-#if BYTE_ORDER == BIG_ENDIAN
- switch(offset)
- {
- case 0:
- mem_word &= 0x0FFF;
- mem_word |= (Rt << 12);
- Mem = mem_word;
- break;
-
- case 1:
- mem_word &= 0x00FF;
- mem_word |= (Rt << 8);
- Mem = mem_word;
- break;
-
- case 2:
- mem_word &= 0x000F;
- mem_word |= (Rt << 4);
- Mem = mem_word;
- break;
-
- case 3:
- Mem = Rt;
- break;
-
- default:
- panic("swr: bad offset");
- }
-#elif BYTE_ORDER == LITTLE_ENDIAN
- switch(offset)
- {
- case 0:
- Mem = Rt;
- break;
-
- case 1:
- mem_word &= 0x000F;
- mem_word |= (Rt << 4);
- Mem = mem_word;
- break;
-
- case 2:
- mem_word &= 0x00FF;
- mem_word |= (Rt << 8);
- Mem = mem_word;
- break;
-
- case 3:
- mem_word &= 0x0FFF;
- mem_word |= (Rt << 12);
- Mem = mem_word;
- break;
-
- default:
- panic("swr: bad offset");
- }
-#endif
- }},{{ EA = (Rs + disp) & ~3;}},mem_flags = NO_ALIGN_FAULT);
}
- format WarnUnimpl {
- 0x7: cache();
+ format StoreUnalignedMemory {
+ 0x2: swl({{ uint32_t reg_shift = 24 - (8 * byte_offset);
+ uint32_t mem_shift = 32 - reg_shift;
+ mem_word = mem_word & (mask(reg_shift) << mem_shift) |
+ Rt.uw >> reg_shift;
+ }});
+ 0x6: swr({{ uint32_t reg_shift = 8 * byte_offset;
+ mem_word = Rt.uw << reg_shift |
+ mem_word & (mask(reg_shift));
+ }});
}
+ 0x7: FailUnimpl::cache();
}
- 0x6: decode OPCODE_LO default FailUnimpl::reserved() {
- 0x0: LoadMemory::ll({{Rt.uw = Mem.uw}},mem_flags=LOCKED);
-
- format LoadFloatMemory {
- 0x1: lwc1({{ Ft.uw = Mem.uw; }});
+ 0x6: decode OPCODE_LO {
+ format LoadMemory {
+ 0x0: ll({{ Rt.uw = Mem.uw; }}, mem_flags=LOCKED);
+ 0x1: lwc1({{ Ft.uw = Mem.uw; }});
0x5: ldc1({{ Ft.ud = Mem.ud; }});
}
+
+ 0x3: Prefetch::pref();
}
- 0x7: decode OPCODE_LO default FailUnimpl::reserved() {
- 0x0: StoreMemory::sc({{ Mem.uw = Rt.uw; Rt.uw = 1; }});
+ 0x7: decode OPCODE_LO {
+ 0x0: StoreCond::sc({{ Mem.uw = Rt.uw;}},
+ {{ uint64_t tmp = write_result;
+ Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw;
+ }}, mem_flags=LOCKED);
- format StoreFloatMemory {
+ format StoreMemory {
0x1: swc1({{ Mem.uw = Ft.uw; }});
0x5: sdc1({{ Mem.ud = Ft.ud; }});
}
diff --git a/src/arch/mips/isa/formats/basic.isa b/src/arch/mips/isa/formats/basic.isa
index c02af7ddc..35ce09205 100644
--- a/src/arch/mips/isa/formats/basic.isa
+++ b/src/arch/mips/isa/formats/basic.isa
@@ -1,5 +1,33 @@
// -*- mode:c++ -*-
+// 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: Korey Sewell
+
// Declarations for execute() methods.
def template BasicExecDeclare {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
@@ -12,11 +40,11 @@ def template BasicDeclare {{
*/
class %(class_name)s : public %(base_class)s
{
- public:
+ public:
/// Constructor.
%(class_name)s(MachInst machInst);
%(BasicExecDeclare)s
- };
+ };
}};
// Basic instruction class constructor template.
@@ -27,6 +55,7 @@ def template BasicConstructor {{
}
}};
+
// Basic instruction class execute method template.
def template BasicExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa
index ea5af22c0..827e3ccf0 100644
--- a/src/arch/mips/isa/formats/branch.isa
+++ b/src/arch/mips/isa/formats/branch.isa
@@ -1,5 +1,33 @@
// -*- mode:c++ -*-
+// 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: Korey Sewell
+
////////////////////////////////////////////////////////////////////
//
// Control transfer instructions
@@ -68,29 +96,6 @@ output header {{
};
/**
- * Base class for branch likely branches (PC-relative control transfers),
- */
- class BranchLikely : public PCDependentDisassembly
- {
- protected:
- /// target address (signed) Displacement .
- int32_t disp;
-
- /// Constructor.
- BranchLikely(const char *mnem, MachInst _machInst, OpClass __opClass)
- : PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(OFFSET << 2)
- {
-
- }
-
- Addr branchTarget(Addr branchPC) const;
-
- std::string
- generateDisassembly(Addr pc, const SymbolTable *symtab) const;
- };
-
- /**
* Base class for jumps (register-indirect control transfers). In
* the Mips ISA, these are always unconditional.
*/
@@ -126,12 +131,6 @@ output decoder {{
}
Addr
- BranchLikely::branchTarget(Addr branchPC) const
- {
- return branchPC + 4 + disp;
- }
-
- Addr
Jump::branchTarget(ThreadContext *tc) const
{
Addr NPC = tc->readPC() + 4;
@@ -171,49 +170,12 @@ output decoder {{
// unconditional branches)
if (_numSrcRegs == 1) {
printReg(ss, _srcRegIdx[0]);
- ss << ",";
+ ss << ", ";
} else if(_numSrcRegs == 2) {
printReg(ss, _srcRegIdx[0]);
- ss << ",";
+ ss << ", ";
printReg(ss, _srcRegIdx[1]);
- ss << ",";
- }
-
- Addr target = pc + 4 + disp;
-
- std::string str;
- if (symtab && symtab->findSymbol(target, str))
- ss << str;
- else
- ccprintf(ss, "0x%x", target);
-
- string inst_name = mnemonic;
-
- if (inst_name.substr(inst_name.length()-2,inst_name.length()) == "al"){
- ccprintf(ss, " (r31=0x%x)",pc+8);
- }
-
- return ss.str();
- }
-
- std::string
- BranchLikely::generateDisassembly(Addr pc, const SymbolTable *symtab) const
- {
- std::stringstream ss;
-
- ccprintf(ss, "%-10s ", mnemonic);
-
- // There's only one register arg (RA), but it could be
- // either a source (the condition for conditional
- // branches) or a destination (the link reg for
- // unconditional branches)
- if (_numSrcRegs > 0) {
- printReg(ss, _srcRegIdx[0]);
- ss << ",";
- }
- else if (_numDestRegs > 0) {
- printReg(ss, _destRegIdx[0]);
- ss << ",";
+ ss << ", ";
}
Addr target = pc + 4 + disp;
@@ -247,72 +209,64 @@ output decoder {{
printReg(ss, _srcRegIdx[0]);
} else if(_numSrcRegs == 2) {
printReg(ss, _srcRegIdx[0]);
- ss << ",";
+ ss << ", ";
printReg(ss, _srcRegIdx[1]);
- } else {
- panic(">= 3 Source Registers!!!");
}
return ss.str();
}
}};
-def format Branch(code,*flags) {{
- #Add Link Code if Link instruction
- strlen = len(name)
- if name[strlen-2:] == 'al':
- code += 'R31 = NNPC;\n'
+def format Branch(code,*opt_flags) {{
+ not_taken_code = ' NNPC = NNPC;\n'
+ not_taken_code += '} \n'
+
+ #Build Instruction Flags
+ #Use Link & Likely Flags to Add Link/Condition Code
+ inst_flags = ('IsDirectControl', )
+ for x in opt_flags:
+ if x == 'Link':
+ code += 'R31 = NNPC;\n'
+ elif x == 'Likely':
+ not_taken_code = ' NPC = NNPC;\n'
+ not_taken_code += ' NNPC = NNPC + 4;\n'
+ not_taken_code += '} \n'
+ inst_flags = ('IsCondDelaySlot', )
+ else:
+ inst_flags += (x, )
+
+ if 'cond == 1' in code:
+ inst_flags += ('IsCondControl', )
+ else:
+ inst_flags += ('IsUncondControl', )
#Condition code
code = 'bool cond;\n' + code
code += 'if (cond) {\n'
code += ' NNPC = NPC + disp;\n'
code += '} else {\n'
- code += ' NNPC = NNPC;\n'
- code += '} \n'
-
- iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
- ('IsDirectControl', 'IsCondControl'))
-
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
-}};
-
-
-def format BranchLikely(code,*flags) {{
- #Add Link Code if Link instruction
- strlen = len(name)
- if name[strlen-3:] == 'all':
- code += 'R31 = NNPC;\n'
-
- #Condition code
- code = 'bool cond;\n' + code
- code += 'if (cond) {'
- code += 'NNPC = NPC + disp;\n'
- code += '} \n'
-
-
- iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
- ('IsDirectControl', 'IsCondControl','IsCondDelaySlot'))
+ code += not_taken_code
+ iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
-def format Jump(code,*flags) {{
- #Add Link Code if Link instruction
- strlen = len(name)
- if strlen > 1 and name[1:] == 'al':
+def format Jump(code, *opt_flags) {{
+ #Build Instruction Flags
+ #Use Link Flag to Add Link Code
+ inst_flags = ('IsIndirectControl', 'IsUncondControl')
+ for x in opt_flags:
+ if x == 'Link':
code = 'R31 = NNPC;\n' + code
+ elif x == 'ClearHazards':
+ code += '/* Code Needed to Clear Execute & Inst Hazards */\n'
+ else:
+ inst_flags += (x, )
-
- iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\
- ('IsIndirectControl', 'IsUncondControl'))
-
+ iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/mips/isa/formats/control.isa b/src/arch/mips/isa/formats/control.isa
new file mode 100644
index 000000000..509ee7e87
--- /dev/null
+++ b/src/arch/mips/isa/formats/control.isa
@@ -0,0 +1,156 @@
+// -*- mode:c++ -*-
+
+// 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: Korey Sewell
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer operate instructions
+//
+
+//Outputs to decoder.hh
+output header {{
+
+ class Control : public MipsStaticInst
+ {
+ protected:
+
+ /// Constructor
+ Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ MipsStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ class CP0Control : public Control
+ {
+ protected:
+
+ /// Constructor
+ CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Control(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ class CP1Control : public Control
+ {
+ protected:
+
+ /// Constructor
+ CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Control(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+}};
+
+//Outputs to decoder.cc
+output decoder {{
+ std::string Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ if (mnemonic == "mfc0" || mnemonic == "mtc0") {
+ ccprintf(ss, "%-10s %d,%d,%d", mnemonic,RT,RD,SEL);
+ } else {
+
+ // just print the first dest... if there's a second one,
+ // it's generally implicit
+ if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ ss << ", ";
+
+ // just print the first two source regs... if there's
+ // a third one, it's a read-modify-write dest (Rc),
+ // e.g. for CMOVxx
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ if (_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+ }
+
+ return ss.str();
+ }
+
+ std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+ ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL);
+ return ss.str();
+ }
+
+ std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+ ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
+ return ss.str();
+ }
+
+}};
+
+def format System(code, *flags) {{
+ iop = InstObjParams(name, Name, 'Control', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format CP0Control(code, *flags) {{
+ iop = InstObjParams(name, Name, 'CP0Control', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format CP1Control(code, *flags) {{
+ iop = InstObjParams(name, Name, 'CP1Control', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+
diff --git a/src/arch/mips/isa/formats/formats.isa b/src/arch/mips/isa/formats/formats.isa
index 7d493ffae..4c3eec132 100644
--- a/src/arch/mips/isa/formats/formats.isa
+++ b/src/arch/mips/isa/formats/formats.isa
@@ -1,5 +1,33 @@
// -*- mode:c++ -*-
+// 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: Korey Sewell
+
//Templates from this format are used later
//Include the basic format
##include "basic.isa"
@@ -10,8 +38,8 @@
//Include utility functions
##include "util.isa"
-//Include the cop0 formats
-##include "cop0.isa"
+//Include the control/cp0/cp1 formats
+##include "control.isa"
//Include the integer formats
##include "int.isa"
@@ -22,6 +50,9 @@
//Include the mem format
##include "mem.isa"
+//Include the mem format
+##include "mt.isa"
+
//Include the trap format
##include "trap.isa"
diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa
index 9f2c24755..d05b04d0e 100644
--- a/src/arch/mips/isa/formats/fp.isa
+++ b/src/arch/mips/isa/formats/fp.isa
@@ -1,5 +1,33 @@
// -*- mode:c++ -*-
+// 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: Korey Sewell
+
////////////////////////////////////////////////////////////////////
//
// Floating Point operate instructions
@@ -18,49 +46,264 @@ output header {{
{
}
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ //needs function to check for fpEnable or not
+ };
+
+ class FPCompareOp : public FPOp
+ {
+ protected:
+ FPCompareOp(const char *mnem, MachInst _machInst, OpClass __opClass) : FPOp(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
};
}};
output decoder {{
- std::string FPOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ std::string FPCompareOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
- return "Disassembly of integer instruction\n";
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ ccprintf(ss,"%d",CC);
+
+ if(_numSrcRegs > 0) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ return ss.str();
}
}};
+output exec {{
-// Primary format for float operate instructions:
-def format FloatOp(code, *flags) {{
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
+ //If any operand is Nan return the appropriate QNaN
+ template <class T>
+ bool
+ fpNanOperands(FPOp *inst, %(CPU_exec_context)s *xc, const T &src_type,
+ Trace::InstRecord *traceData)
+ {
+ uint64_t mips_nan = 0;
+ T src_op = 0;
+ int size = sizeof(src_op) * 8;
+
+ for (int i = 0; i < inst->numSrcRegs(); i++) {
+ uint64_t src_bits = xc->readFloatRegBits(inst, 0, size);
+
+ if (isNan(&src_bits, size) ) {
+ if (isSnan(&src_bits, size)) {
+ switch (size)
+ {
+ case 32: mips_nan = MIPS32_QNAN; break;
+ case 64: mips_nan = MIPS64_QNAN; break;
+ default: panic("Unsupported Floating Point Size (%d)", size);
+ }
+ } else {
+ mips_nan = src_bits;
+ }
+
+ xc->setFloatRegBits(inst, 0, mips_nan, size);
+ if (traceData) { traceData->setData(mips_nan); }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template <class T>
+ bool
+ fpInvalidOp(FPOp *inst, %(CPU_exec_context)s *cpu, const T dest_val,
+ Trace::InstRecord *traceData)
+ {
+ uint64_t mips_nan = 0;
+ T src_op = dest_val;
+ int size = sizeof(src_op) * 8;
+
+ if (isNan(&src_op, size)) {
+ switch (size)
+ {
+ case 32: mips_nan = MIPS32_QNAN; break;
+ case 64: mips_nan = MIPS64_QNAN; break;
+ default: panic("Unsupported Floating Point Size (%d)", size);
+ }
+
+ //Set value to QNAN
+ cpu->setFloatRegBits(inst, 0, mips_nan, size);
+
+ //Read FCSR from FloatRegFile
+ uint32_t fcsr_bits = cpu->tc->readFloatRegBits(FCSR);
+
+ //Write FCSR from FloatRegFile
+ cpu->tc->setFloatRegBits(FCSR, genInvalidVector(fcsr_bits));
+
+ if (traceData) { traceData->setData(mips_nan); }
+ return true;
+ }
+
+ return false;
+ }
+
+ void
+ fpResetCauseBits(%(CPU_exec_context)s *cpu)
+ {
+ //Read FCSR from FloatRegFile
+ uint32_t fcsr = cpu->tc->readFloatRegBits(FCSR);
+
+ fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);
+
+ //Write FCSR from FloatRegFile
+ cpu->tc->setFloatRegBits(FCSR, fcsr);
+ }
}};
-def format FloatCompareOp(code, *flags) {{
- code = 'bool cond;\n' + code
- code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
+def template FloatingPointExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+
+ //When is the right time to reset cause bits?
+ //start of every instruction or every cycle?
+ fpResetCauseBits(xc);
+
+ %(op_decl)s;
+ %(op_rd)s;
+
+ //Check if any FP operand is a NaN value
+ if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
+ %(code)s;
+
+ //Change this code for Full-System/Sycall Emulation
+ //separation
+ //----
+ //Should Full System-Mode throw a fault here?
+ //----
+ //Check for IEEE 754 FP Exceptions
+ //fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);
+ if (!fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&
+ fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+ }
+
+ return fault;
+ }
}};
-def format FloatCompareWithXcptOp(code, *flags) {{
- code = 'bool cond;\n' + code
- code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+// Primary format for float point operate instructions:
+def format FloatOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
+ exec_output = FloatingPointExecute.subst(iop)
+}};
+
+def format FloatCompareOp(cond_code, *flags) {{
+ import sys
+
+ code = 'bool cond;\n'
+ if '.sf' in cond_code or 'SinglePrecision' in flags:
+ if 'QnanException' in flags:
+ code += 'if (isQnan(&Fs.sf, 32) || isQnan(&Ft.sf, 32)) {\n'
+ code += '\tFCSR = genInvalidVector(FCSR);\n'
+ code += '\treturn NoFault;'
+ code += '}\n else '
+ code += 'if (isNan(&Fs.sf, 32) || isNan(&Ft.sf, 32)) {\n'
+ elif '.df' in cond_code or 'DoublePrecision' in flags:
+ if 'QnanException' in flags:
+ code += 'if (isQnan(&Fs.df, 64) || isQnan(&Ft.df, 64)) {\n'
+ code += '\tFCSR = genInvalidVector(FCSR);\n'
+ code += '\treturn NoFault;'
+ code += '}\n else '
+ code += 'if (isNan(&Fs.df, 64) || isNan(&Ft.df, 64)) {\n'
+ else:
+ sys.exit('Decoder Failed: Can\'t Determine Operand Type\n')
+
+ if 'UnorderedTrue' in flags:
+ code += 'cond = 1;\n'
+ elif 'UnorderedFalse' in flags:
+ code += 'cond = 0;\n'
+ else:
+ sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
+
+ code += '} else {\n'
+ code += cond_code + '}'
+ code += 'FCSR = genCCVector(FCSR, CC, cond);\n'
+
+ iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
}};
def format FloatConvertOp(code, *flags) {{
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+ import sys
+
+ #Determine Source Type
+ convert = 'fpConvert('
+ if '.sf' in code:
+ code = 'float ' + code + '\n'
+ convert += 'SINGLE_TO_'
+ elif '.df' in code:
+ code = 'double ' + code + '\n'
+ convert += 'DOUBLE_TO_'
+ elif '.uw' in code:
+ code = 'uint32_t ' + code + '\n'
+ convert += 'WORD_TO_'
+ elif '.ud' in code:
+ code = 'uint64_t ' + code + '\n'
+ convert += 'LONG_TO_'
+ else:
+ sys.exit("Error Determining Source Type for Conversion")
+
+ #Determine Destination Type
+ if 'ToSingle' in flags:
+ code += 'Fd.uw = ' + convert + 'SINGLE, '
+ elif 'ToDouble' in flags:
+ code += 'Fd.ud = ' + convert + 'DOUBLE, '
+ elif 'ToWord' in flags:
+ code += 'Fd.uw = ' + convert + 'WORD, '
+ elif 'ToLong' in flags:
+ code += 'Fd.ud = ' + convert + 'LONG, '
+ else:
+ sys.exit("Error Determining Destination Type for Conversion")
+
+ #Figure out how to round value
+ if 'Ceil' in flags:
+ code += 'ceil(val)); '
+ elif 'Floor' in flags:
+ code += 'floor(val)); '
+ elif 'Round' in flags:
+ code += 'roundFP(val, 0)); '
+ elif 'Trunc' in flags:
+ code += 'truncFP(val));'
+ else:
+ code += 'val); '
+
+ iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format FloatAccOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -76,34 +319,51 @@ def format Float64Op(code, *flags) {{
exec_output = BasicExecute.subst(iop)
}};
-def format Float64ConvertOp(code, *flags) {{
- code = 'bool cond;\n' + code
- code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
-}};
+def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{
+ import sys
-def format FloatPSCompareOp(code, *flags) {{
- code = 'bool cond1;\nbool cond2;\n' + code
- code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
- code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
-}};
+ code = 'bool cond1, cond2;\n'
+ code += 'bool code_block1, code_block2;\n'
+ code += 'code_block1 = code_block2 = true;\n'
-def format FloatPSCompareWithXcptOp(code, *flags) {{
- code = 'bool cond1;\nbool cond2;\n' + code
- code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
- code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
- iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
+ if 'QnanException' in flags:
+ code += 'if (isQnan(&Fs1.sf, 32) || isQnan(&Ft1.sf, 32)) {\n'
+ code += '\tFCSR = genInvalidVector(FCSR);\n'
+ code += 'code_block1 = false;'
+ code += '}\n'
+ code += 'if (isQnan(&Fs2.sf, 32) || isQnan(&Ft2.sf, 32)) {\n'
+ code += '\tFCSR = genInvalidVector(FCSR);\n'
+ code += 'code_block2 = false;'
+ code += '}\n'
+
+ code += 'if (code_block1) {'
+ code += '\tif (isNan(&Fs1.sf, 32) || isNan(&Ft1.sf, 32)) {\n'
+ if 'UnorderedTrue' in flags:
+ code += 'cond1 = 1;\n'
+ elif 'UnorderedFalse' in flags:
+ code += 'cond1 = 0;\n'
+ else:
+ sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
+ code += '} else {\n'
+ code += cond_code1
+ code += 'FCSR = genCCVector(FCSR, CC, cond1);}\n}\n'
+
+ code += 'if (code_block2) {'
+ code += '\tif (isNan(&Fs2.sf, 32) || isNan(&Ft2.sf, 32)) {\n'
+ if 'UnorderedTrue' in flags:
+ code += 'cond2 = 1;\n'
+ elif 'UnorderedFalse' in flags:
+ code += 'cond2 = 0;\n'
+ else:
+ sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
+ code += '} else {\n'
+ code += cond_code2
+ code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}'
+
+ iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
}};
+
diff --git a/src/arch/mips/isa/formats/int.isa b/src/arch/mips/isa/formats/int.isa
index 7d38b9ff5..7b5affb5c 100644
--- a/src/arch/mips/isa/formats/int.isa
+++ b/src/arch/mips/isa/formats/int.isa
@@ -1,11 +1,37 @@
// -*- mode:c++ -*-
+// 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: Korey Sewell
+
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
-
-//Outputs to decoder.hh
output header {{
#include <iostream>
using namespace std;
@@ -25,6 +51,34 @@ output header {{
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
+
+ class HiLoOp: public IntOp
+ {
+ protected:
+
+ /// Constructor
+ HiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntOp(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ class HiLoMiscOp: public HiLoOp
+ {
+ protected:
+
+ /// Constructor
+ HiLoMiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ HiLoOp(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+
class IntImmOp : public MipsStaticInst
{
protected:
@@ -52,6 +106,33 @@ output header {{
}};
+// HiLo<Misc> instruction class execute method template.
+// Mainly to get instruction trace data to print out
+// correctly
+def template HiLoExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ if(fault == NoFault)
+ {
+ %(op_wb)s;
+ //If there are 2 Destination Registers then
+ //concatenate the values for the traceData
+ if(traceData && _numDestRegs == 2) {
+ uint64_t hilo_final_val = (uint64_t)HI << 32 | LO;
+ traceData->setData(hilo_final_val);
+ }
+ }
+ return fault;
+ }
+}};
+
//Outputs to decoder.cc
output decoder {{
std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
@@ -64,7 +145,7 @@ output decoder {{
// it's generally implicit
if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
- ss << ",";
+ ss << ", ";
}
// just print the first two source regs... if there's
@@ -75,13 +156,47 @@ output decoder {{
}
if (_numSrcRegs > 1) {
- ss << ",";
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ return ss.str();
+ }
+
+ std::string HiLoOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ //Destination Registers are implicit for HI/LO ops
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ if (_numSrcRegs > 1) {
+ ss << ", ";
printReg(ss, _srcRegIdx[1]);
}
return ss.str();
}
+ std::string HiLoMiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
+ printReg(ss, _destRegIdx[0]);
+ } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ return ss.str();
+ }
+
std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
@@ -92,15 +207,15 @@ output decoder {{
printReg(ss, _destRegIdx[0]);
}
- ss << ",";
+ ss << ", ";
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
- ss << ",";
+ ss << ", ";
}
if( mnemonic == "lui")
- ccprintf(ss, "%08p ", sextImm);
+ ccprintf(ss, "0x%x ", sextImm);
else
ss << (int) sextImm;
@@ -109,23 +224,47 @@ output decoder {{
}};
-//Used by decoder.isa
def format IntOp(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
-
- # Figure out if we are creating a IntImmOp or a IntOp
- # by looking at the instruction name
- iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags)
- strlen = len(name)
- if name[strlen-1] == 'i' or name[strlen-2:] == 'iu':
- iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags)
-
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = OperateNopCheckDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
+ iop = InstObjParams(name, Name, 'IntOp', CodeBlock(code), opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = OperateNopCheckDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format IntImmOp(code, *opt_flags) {{
+ iop = InstObjParams(name, Name, 'IntImmOp', CodeBlock(code), opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = OperateNopCheckDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format HiLoOp(code, *opt_flags) {{
+ if '.sd' in code:
+ code = 'int64_t ' + code
+ elif '.ud' in code:
+ code = 'uint64_t ' + code
+
+ code += 'HI = val<63:32>;\n'
+ code += 'LO = val<31:0>;\n'
+
+ iop = InstObjParams(name, Name, 'HiLoOp', CodeBlock(code), opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = OperateNopCheckDecode.subst(iop)
+ exec_output = HiLoExecute.subst(iop)
}};
+def format HiLoMiscOp(code, *opt_flags) {{
+ iop = InstObjParams(name, Name, 'HiLoMiscOp', CodeBlock(code), opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = OperateNopCheckDecode.subst(iop)
+ exec_output = HiLoExecute.subst(iop)
+}};
+
+
+
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
index d5436b308..f52247056 100644
--- a/src/arch/mips/isa/formats/mem.isa
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -31,7 +31,7 @@
////////////////////////////////////////////////////////////////////
//
-// Memory-format instructions: LoadAddress, Load, Store
+// Memory-format instructions
//
output header {{
@@ -90,15 +90,6 @@ output decoder {{
}};
-def format LoadAddress(code) {{
- iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
-}};
-
-
def template LoadStoreDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
@@ -426,8 +417,70 @@ def template StoreCompleteAcc {{
}
}};
+
+def template MiscMemAccExecute {{
+ Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ EA = xc->getEA();
+
+ if (fault == NoFault) {
+ %(code)s;
+ }
+
+ return NoFault;
+ }
+}};
+
+def template MiscExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ return NoFault;
+ }
+}};
+
+def template MiscInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("Misc instruction does not support split access method!");
+ return NoFault;
+ }
+}};
+
+
+def template MiscCompleteAcc {{
+ Fault %(class_name)s::completeAcc(uint8_t *data,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("Misc instruction does not support split access method!");
+
+ return NoFault;
+ }
+}};
+
// load instructions use Rt as dest, so check for
-// Rt == 31 to detect nops
+// Rt == 0 to detect nops
def template LoadNopCheckDecode {{
{
MipsStaticInst *i = new %(class_name)s(machInst);
@@ -446,7 +499,6 @@ def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
exec_template_base = 'Load')
}};
-
def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
@@ -454,26 +506,70 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
exec_template_base = 'Store')
}};
-//FP loads are offloaded to these formats for now ...
-def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
+def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- decode_template = BasicDecode,
+ decode_template = LoadNopCheckDecode,
exec_template_base = 'Load')
}};
+def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ exec_template_base = 'Store')
+}};
+
+def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
+ mem_flags = [], inst_flags = []) {{
+ decl_code = 'uint32_t mem_word = Mem.uw;\n'
+ decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
+ decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
+ decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
+ decl_code += '\tbyte_offset ^= 3;\n'
+ decl_code += '#endif\n'
+
+ memacc_code = decl_code + memacc_code
+
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ decode_template = LoadNopCheckDecode,
+ exec_template_base = 'Load')
+}};
-def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
+def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
mem_flags = [], inst_flags = []) {{
+ decl_code = 'uint32_t mem_word = 0;\n'
+ decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
+ decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
+ decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
+ decl_code += '\tbyte_offset ^= 3;\n'
+ decl_code += '#endif\n'
+ decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
+ memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
+
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ decode_template = LoadNopCheckDecode,
exec_template_base = 'Store')
}};
+def format Prefetch(ea_code = {{ EA = Rs + disp; }},
+ mem_flags = [], pf_flags = [], inst_flags = []) {{
+ pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
+ pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
+ 'IsDataPrefetch', 'MemReadOp']
+
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code,
+ 'xc->prefetch(EA, memAccessFlags);',
+ pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
+
+}};
-def format UnalignedStore(memacc_code, postacc_code,
- ea_code = {{ EA = Rb + disp; }},
+def format StoreCond(memacc_code, postacc_code,
+ ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa
new file mode 100644
index 000000000..521b01123
--- /dev/null
+++ b/src/arch/mips/isa/formats/mt.isa
@@ -0,0 +1,81 @@
+// -*- mode:c++ -*-
+
+// 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: Korey Sewell
+
+////////////////////////////////////////////////////////////////////
+//
+// MT instructions
+//
+
+output header {{
+ /**
+ * Base class for integer operations.
+ */
+ class MT : public MipsStaticInst
+ {
+ protected:
+
+ /// Constructor
+ MT(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ //Edit This Template When MT is Implemented
+ std::string MT::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return "Disassembly of MT instruction\n";
+ }
+}};
+
+def template MTExecute {{
+ //Edit This Template When MT is Implemented
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+
+ //Call into the trap handler with the appropriate fault
+ return No_Fault;
+ }
+}};
+
+// Primary format for integer operate instructions:
+def format MipsMT() {{
+ code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n'
+ iop = InstObjParams(name, Name, 'MT', CodeBlock(code))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/mips/isa/formats/noop.isa b/src/arch/mips/isa/formats/noop.isa
index 2aa4816e3..4fd8235e4 100644
--- a/src/arch/mips/isa/formats/noop.isa
+++ b/src/arch/mips/isa/formats/noop.isa
@@ -1,5 +1,33 @@
// -*- mode:c++ -*-
+// 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: Korey Sewell
+
////////////////////////////////////////////////////////////////////
//
// Nop
@@ -36,11 +64,7 @@ output decoder {{
std::string Nop::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
-#ifdef SS_COMPATIBLE_DISASSEMBLY
- return originalDisassembly;
-#else
- return csprintf("%-10s (%s)", "nop", originalDisassembly);
-#endif
+ return csprintf("%-10s %s", "nop", originalDisassembly);
}
/// Helper function for decoding nops. Substitute Nop object
@@ -89,6 +113,6 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{
}};
def format Nop() {{
- decode_block = 'return new Nop(\"sll r0,r0,0\",machInst);\n'
+ decode_block = 'return new Nop(\"\",machInst);\n'
}};
diff --git a/src/arch/mips/isa/formats/tlbop.isa b/src/arch/mips/isa/formats/tlbop.isa
index f5e4076f2..75ab71c48 100644
--- a/src/arch/mips/isa/formats/tlbop.isa
+++ b/src/arch/mips/isa/formats/tlbop.isa
@@ -1,3 +1,33 @@
+// -*- mode:c++ -*-
+
+// 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: Korey Sewell
+
////////////////////////////////////////////////////////////////////
//
// TlbOp instructions
@@ -30,13 +60,10 @@ output decoder {{
def template TlbOpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
- //Call into the trap handler with the appropriate fault
- return No_Fault;
- }
-
//Write the resulting state to the execution context
%(op_wb)s;
+ //Call into the trap handler with the appropriate fault
return No_Fault;
}
}};
diff --git a/src/arch/mips/isa/formats/trap.isa b/src/arch/mips/isa/formats/trap.isa
index 6884d4fa8..574b808cc 100644
--- a/src/arch/mips/isa/formats/trap.isa
+++ b/src/arch/mips/isa/formats/trap.isa
@@ -1,3 +1,33 @@
+// -*- mode:c++ -*-
+
+// 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: Korey Sewell
+
////////////////////////////////////////////////////////////////////
//
// Trap instructions
@@ -23,27 +53,26 @@ output header {{
output decoder {{
std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
- return "Disassembly of integer instruction\n";
+ return "Disassembly of trap instruction\n";
}
}};
def template TrapExecute {{
+ //Edit This Template When Traps Are Implemented
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
- //Call into the trap handler with the appropriate fault
- return No_Fault;
- }
-
//Write the resulting state to the execution context
%(op_wb)s;
+ //Call into the trap handler with the appropriate fault
return No_Fault;
}
}};
-// Primary format for integer operate instructions:
def format Trap(code, *flags) {{
- code = 'bool cond;\n' + code;
+ code = 'panic(\"'
+ code += 'Trap Exception Handler Is Currently Not Implemented.'
+ code += '\");'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/src/arch/mips/isa/formats/unimp.isa b/src/arch/mips/isa/formats/unimp.isa
index 8e42da499..e17b5f832 100644
--- a/src/arch/mips/isa/formats/unimp.isa
+++ b/src/arch/mips/isa/formats/unimp.isa
@@ -1,5 +1,6 @@
// -*- mode:c++ -*-
+
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// All rights reserved.
//
@@ -103,11 +104,7 @@ output decoder {{
WarnUnimplemented::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
-#ifdef SS_COMPATIBLE_DISASSEMBLY
- return csprintf("%-10s", mnemonic);
-#else
return csprintf("%-10s (unimplemented)", mnemonic);
-#endif
}
}};
@@ -127,7 +124,7 @@ output exec {{
Trace::InstRecord *traceData) const
{
if (!warned) {
- warn("instruction '%s' unimplemented\n", mnemonic);
+ warn("\tinstruction '%s' unimplemented\n", mnemonic);
warned = true;
}
@@ -146,28 +143,3 @@ def format WarnUnimpl() {{
decode_block = BasicDecodeWithMnemonic.subst(iop)
}};
-output header {{
- /**
- * Static instruction class for unknown (illegal) instructions.
- * These cause simulator termination if they are executed in a
- * non-speculative mode. This is a leaf class.
- */
- class Unknown : public MipsStaticInst
- {
- public:
- /// Constructor
- Unknown(MachInst _machInst)
- : MipsStaticInst("unknown", _machInst, No_OpClass)
- {
- // don't call execute() (which panics) if we're on a
- // speculative path
- flags[IsNonSpeculative] = true;
- }
-
- %(BasicExecDeclare)s
-
- std::string
- generateDisassembly(Addr pc, const SymbolTable *symtab) const;
- };
-}};
-
diff --git a/src/arch/mips/isa/formats/unknown.isa b/src/arch/mips/isa/formats/unknown.isa
index 7c2275598..41387adca 100644
--- a/src/arch/mips/isa/formats/unknown.isa
+++ b/src/arch/mips/isa/formats/unknown.isa
@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
-// Copyright (c) 2003-2005 The Regents of The University of Michigan
+// 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
@@ -34,28 +34,31 @@
//
output header {{
- std::string inst2string(MachInst machInst);
-}};
-output decoder {{
-
-std::string inst2string(MachInst machInst)
-{
- string str = "";
- uint32_t mask = 0x80000000;
-
- for(int i=0; i < 32; i++) {
- if ((machInst & mask) == 0) {
- str += "0";
- } else {
- str += "1";
+ /**
+ * Static instruction class for unknown (illegal) instructions.
+ * These cause simulator termination if they are executed in a
+ * non-speculative mode. This is a leaf class.
+ */
+ class Unknown : public MipsStaticInst
+ {
+ public:
+ /// Constructor
+ Unknown(MachInst _machInst)
+ : MipsStaticInst("unknown", _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
}
- mask = mask >> 1;
- }
+ %(BasicExecDeclare)s
- return str;
-}
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+output decoder {{
std::string
Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa
index 615160931..b67a02d07 100644
--- a/src/arch/mips/isa/formats/util.isa
+++ b/src/arch/mips/isa/formats/util.isa
@@ -1,5 +1,34 @@
// -*- mode:c++ -*-
+// 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
+// Korey Sewell
+
let {{
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
postacc_code = '', base_class = 'Memory',
@@ -90,7 +119,31 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ completeAccTemplate.subst(completeacc_iop))
}};
+output header {{
+ std::string inst2string(MachInst machInst);
+}};
+
+output decoder {{
+
+std::string inst2string(MachInst machInst)
+{
+ string str = "";
+ uint32_t mask = 0x80000000;
+
+ for(int i=0; i < 32; i++) {
+ if ((machInst & mask) == 0) {
+ str += "0";
+ } else {
+ str += "1";
+ }
+ mask = mask >> 1;
+ }
+
+ return str;
+}
+
+}};
output exec {{
using namespace MipsISA;
@@ -124,6 +177,7 @@ output exec {{
#endif
+
}};
diff --git a/src/arch/mips/isa/includes.isa b/src/arch/mips/isa/includes.isa
index 9c370fbe3..555cec255 100644
--- a/src/arch/mips/isa/includes.isa
+++ b/src/arch/mips/isa/includes.isa
@@ -1,3 +1,33 @@
+// -*- mode:c++ -*-
+
+// 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: Korey Sewell
+
////////////////////////////////////////////////////////////////////
//
// Output include file directives.
@@ -16,9 +46,10 @@ output decoder {{
#include "arch/mips/isa_traits.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
-#include "cpu/exec_context.hh" // for Jump::branchTarget()
+#include "cpu/thread_context.hh"
#include "arch/mips/faults.hh"
#include "arch/mips/isa_traits.hh"
+#include "arch/mips/utility.hh"
#include <math.h>
#if defined(linux)
@@ -31,6 +62,8 @@ using namespace MipsISA;
output exec {{
#include "arch/mips/faults.hh"
#include "arch/mips/isa_traits.hh"
+#include "arch/mips/utility.hh"
+
#include <math.h>
#if defined(linux)
#include <fenv.h>
diff --git a/src/arch/mips/isa/operands.isa b/src/arch/mips/isa/operands.isa
index 0f9c74b48..316552ef4 100644
--- a/src/arch/mips/isa/operands.isa
+++ b/src/arch/mips/isa/operands.isa
@@ -1,3 +1,33 @@
+// -*- mode:c++ -*-
+
+// 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: Korey Sewell
+
def operand_types {{
'sb' : ('signed int', 8),
'ub' : ('unsigned int', 8),
diff --git a/src/arch/mips/isa_traits.cc b/src/arch/mips/isa_traits.cc
index 056c8baff..9f3817a60 100644
--- a/src/arch/mips/isa_traits.cc
+++ b/src/arch/mips/isa_traits.cc
@@ -42,6 +42,7 @@ using namespace std;
void
MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
{
+ panic("Copy Regs Not Implemented Yet\n");
/*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
@@ -55,6 +56,7 @@ MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
void
MipsISA::MiscRegFile::copyMiscRegs(ThreadContext *tc)
{
+ panic("Copy Misc. Regs Not Implemented Yet\n");
/*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
@@ -63,77 +65,6 @@ MipsISA::MiscRegFile::copyMiscRegs(ThreadContext *tc)
#endif*/
}
-uint64_t
-MipsISA::fpConvert(double fp_val, ConvertType cvt_type)
-{
-
- switch (cvt_type)
- {
- case SINGLE_TO_DOUBLE:
- double sdouble_val = fp_val;
- void *sdouble_ptr = &sdouble_val;
- uint64_t sdp_bits = *(uint64_t *) sdouble_ptr;
- return sdp_bits;
-
- case SINGLE_TO_WORD:
- int32_t sword_val = (int32_t) fp_val;
- void *sword_ptr = &sword_val;
- uint64_t sword_bits= *(uint32_t *) sword_ptr;
- return sword_bits;
-
- case WORD_TO_SINGLE:
- float wfloat_val = fp_val;
- void *wfloat_ptr = &wfloat_val;
- uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
- return wfloat_bits;
-
- case WORD_TO_DOUBLE:
- double wdouble_val = fp_val;
- void *wdouble_ptr = &wdouble_val;
- uint64_t wdp_bits = *(uint64_t *) wdouble_ptr;
- return wdp_bits;
-
- default:
- panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
- return 0;
- }
-}
-
-double
-MipsISA::roundFP(double val, int digits)
-{
- double digit_offset = pow(10.0,digits);
- val = val * digit_offset;
- val = val + 0.5;
- val = floor(val);
- val = val / digit_offset;
- return val;
-}
-
-double
-MipsISA::truncFP(double val)
-{
- int trunc_val = (int) val;
- return (double) trunc_val;
-}
-
-bool
-MipsISA::getFPConditionCode(uint32_t fcsr_reg, int cc)
-{
- //uint32_t cc_bits = xc->readFloatReg(35);
- return false;//regFile.floatRegfile.getConditionCode(cc);
-}
-
-uint32_t
-MipsISA::makeCCVector(uint32_t fcsr, int num, bool val)
-{
- int shift = (num == 0) ? 22 : num + 23;
-
- fcsr = fcsr | (val << shift);
-
- return fcsr;
-}
-
#if FULL_SYSTEM
static inline Addr
diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc
index 4a919ac27..17e735527 100644
--- a/src/arch/mips/linux/process.cc
+++ b/src/arch/mips/linux/process.cc
@@ -135,7 +135,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>),
/* 16 */ SyscallDesc("lchown", chownFunc),
- /* 17 */ SyscallDesc("break", obreakFunc), /*obreak*/
+ /* 17 */ SyscallDesc("break", obreakFunc),
/* 18 */ SyscallDesc("unused#18", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc),
@@ -163,7 +163,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
/* 43 */ SyscallDesc("times", unimplementedFunc),
/* 44 */ SyscallDesc("prof", unimplementedFunc),
- /* 45 */ SyscallDesc("brk", obreakFunc),/*openFunc<MipsLinux>*/
+ /* 45 */ SyscallDesc("brk", obreakFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidFunc),
/* 48 */ SyscallDesc("signal", ignoreFunc),
@@ -173,7 +173,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 52 */ SyscallDesc("umount2", unimplementedFunc),
/* 53 */ SyscallDesc("lock", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>),
- /* 55 */ SyscallDesc("fcntl", unimplementedFunc),
+ /* 55 */ SyscallDesc("fcntl", fcntlFunc),
/* 56 */ SyscallDesc("mpx", unimplementedFunc),
/* 57 */ SyscallDesc("setpgid", unimplementedFunc),
/* 58 */ SyscallDesc("ulimit", unimplementedFunc),
@@ -210,8 +210,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 89 */ SyscallDesc("readdir", unimplementedFunc),
/* 90 */ SyscallDesc("mmap", mmapFunc<MipsLinux>),
/* 91 */ SyscallDesc("munmap",munmapFunc),
- /* 92 */ SyscallDesc("truncate", fcntlFunc),
- /* 93 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 92 */ SyscallDesc("truncate", truncateFunc),
+ /* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 94 */ SyscallDesc("fchmod", unimplementedFunc),
/* 95 */ SyscallDesc("fchown", unimplementedFunc),
/* 96 */ SyscallDesc("getpriority", unimplementedFunc),
@@ -262,7 +262,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 141 */ SyscallDesc("getdents", unimplementedFunc),
/* 142 */ SyscallDesc("newselect", unimplementedFunc),
/* 143 */ SyscallDesc("flock", unimplementedFunc),
- /* 144 */ SyscallDesc("msync", unimplementedFunc),/*getrlimitFunc<MipsLinux>*/
+ /* 144 */ SyscallDesc("msync", unimplementedFunc),
/* 145 */ SyscallDesc("readv", unimplementedFunc),
/* 146 */ SyscallDesc("writev", writevFunc<MipsLinux>),
/* 147 */ SyscallDesc("cacheflush", unimplementedFunc),
@@ -338,7 +338,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 217 */ SyscallDesc("mincore", unimplementedFunc),
/* 218 */ SyscallDesc("madvise", unimplementedFunc),
/* 219 */ SyscallDesc("getdents64", unimplementedFunc),
- /* 220 */ SyscallDesc("fcntl64", fcntlFunc),
+ /* 220 */ SyscallDesc("fcntl64", fcntl64Func),
/* 221 */ SyscallDesc("reserved#221", unimplementedFunc),
/* 222 */ SyscallDesc("gettid", unimplementedFunc),
/* 223 */ SyscallDesc("readahead", unimplementedFunc),
@@ -414,9 +414,7 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
: MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
argv, envp),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
-{
- //init_regs->intRegFile[0] = 0;
-}
+{ }
SyscallDesc*
MipsLinuxProcess::getDesc(int callnum)
diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh
index 2c2dadc8b..68da3227b 100644
--- a/src/arch/mips/linux/process.hh
+++ b/src/arch/mips/linux/process.hh
@@ -24,8 +24,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Korey Sewell
*/
#ifndef __MIPS_LINUX_PROCESS_HH__
diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc
index bd7aa394e..7762c2fa0 100644
--- a/src/arch/mips/process.cc
+++ b/src/arch/mips/process.cc
@@ -27,74 +27,38 @@
*
* Authors: Gabe Black
* Ali Saidi
+ * Korey Sewell
*/
#include "arch/mips/isa_traits.hh"
#include "arch/mips/process.hh"
-#include "arch/mips/linux/process.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
-#include "sim/builder.hh"
#include "sim/system.hh"
using namespace std;
using namespace MipsISA;
-
-MipsLiveProcess *
-MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
- int stdout_fd, int stderr_fd, std::string executable,
- std::vector<std::string> &argv, std::vector<std::string> &envp)
-{
- MipsLiveProcess *process = NULL;
-
- ObjectFile *objFile = createObjectFile(executable);
- if (objFile == NULL) {
- fatal("Can't load object file %s", executable);
- }
-
-
- if (objFile->getArch() != ObjectFile::Mips)
- fatal("Object file does not match architecture.");
- switch (objFile->getOpSys()) {
- case ObjectFile::Linux:
- process = new MipsLinuxProcess(nm, objFile, system,
- stdin_fd, stdout_fd, stderr_fd,
- argv, envp);
- break;
-
- default:
- fatal("Unknown/unsupported operating system.");
- }
-
- if (process == NULL)
- fatal("Unknown error creating process object.");
- return process;
-}
-
MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile,
System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv, std::vector<std::string> &envp)
: LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
argv, envp)
{
+ // Set up stack. On MIPS, stack starts at the top of kuseg
+ // user address space. MIPS stack grows down from here
+ stack_base = 0x7FFFFFFF;
- // XXX all the below need to be updated for SPARC - Ali
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+ // Set up break point (Top of Heap)
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
brk_point = roundUp(brk_point, VMPageSize);
- // Set up stack. On Alpha, stack goes below text section. This
- // code should get moved to some architecture-specific spot.
- stack_base = objFile->textBase() - (409600+4096);
-
- // Set up region for mmaps. Tru64 seems to start just above 0 and
- // grow up from there.
+ // Set up region for mmaps. For now, start at bottom of kuseg space.
mmap_start = mmap_end = 0x10000;
-
- // Set pointer for next thread stack. Reserve 8M for main stack.
- next_thread_stack_base = stack_base - (8 * 1024 * 1024);
-
}
void
@@ -102,63 +66,3 @@ MipsLiveProcess::startup()
{
argsInit(MachineBytes, VMPageSize);
}
-
-
-
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
-
- VectorParam<string> cmd;
- Param<string> executable;
- Param<string> input;
- Param<string> output;
- VectorParam<string> env;
- SimObjectParam<System *> system;
-
-END_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
-
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
-
- INIT_PARAM(cmd, "command line (executable plus arguments)"),
- INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
- INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
- INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
- INIT_PARAM(env, "environment settings"),
- INIT_PARAM(system, "system")
-
-END_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
-
-
-CREATE_SIM_OBJECT(MipsLiveProcess)
-{
- string in = input;
- string out = output;
-
- // initialize file descriptors to default: same as simulator
- int stdin_fd, stdout_fd, stderr_fd;
-
- if (in == "stdin" || in == "cin")
- stdin_fd = STDIN_FILENO;
- else
- stdin_fd = Process::openInputFile(input);
-
- if (out == "stdout" || out == "cout")
- stdout_fd = STDOUT_FILENO;
- else if (out == "stderr" || out == "cerr")
- stdout_fd = STDERR_FILENO;
- else
- stdout_fd = Process::openOutputFile(out);
-
- stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
-
- return MipsLiveProcess::create(getInstanceName(), system,
- stdin_fd, stdout_fd, stderr_fd,
- (string)executable == "" ? cmd[0] : executable,
- cmd, env);
-}
-
-
-REGISTER_SIM_OBJECT("MipsLiveProcess", MipsLiveProcess)
-
-
diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh
index 45513af46..b0ef20399 100644
--- a/src/arch/mips/process.hh
+++ b/src/arch/mips/process.hh
@@ -27,6 +27,7 @@
*
* Authors: Gabe Black
* Ali Saidi
+ * Korey Sewell
*/
#ifndef __MIPS_PROCESS_HH__
@@ -49,18 +50,6 @@ class MipsLiveProcess : public LiveProcess
std::vector<std::string> &envp);
void startup();
-
- public:
- // this function is used to create the LiveProcess object, since
- // we can't tell which subclass of LiveProcess to use until we
- // open and look at the object file.
- static MipsLiveProcess *create(const std::string &nm,
- System *_system,
- int stdin_fd, int stdout_fd, int stderr_fd,
- std::string executable,
- std::vector<std::string> &argv,
- std::vector<std::string> &envp);
-
};
diff --git a/src/arch/mips/regfile/float_regfile.hh b/src/arch/mips/regfile/float_regfile.hh
index 013aa01c7..d1a60298a 100644
--- a/src/arch/mips/regfile/float_regfile.hh
+++ b/src/arch/mips/regfile/float_regfile.hh
@@ -62,13 +62,17 @@ namespace MipsISA
switch(width)
{
case SingleWidth:
- void *float_ptr = &regs[floatReg];
- return *(float *) float_ptr;
+ {
+ void *float_ptr = &regs[floatReg];
+ return *(float *) float_ptr;
+ }
case DoubleWidth:
- uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
- void *double_ptr = &double_val;
- return *(double *) double_ptr;
+ {
+ uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
+ void *double_ptr = &double_val;
+ return *(double *) double_ptr;
+ }
default:
panic("Attempted to read a %d bit floating point register!", width);
@@ -99,21 +103,24 @@ namespace MipsISA
Fault setReg(int floatReg, const FloatReg &val, int width)
{
-
switch(width)
{
case SingleWidth:
- float temp = val;
- void *float_ptr = &temp;
- regs[floatReg] = *(FloatReg32 *) float_ptr;
- break;
+ {
+ float temp = val;
+ void *float_ptr = &temp;
+ regs[floatReg] = *(FloatReg32 *) float_ptr;
+ break;
+ }
case DoubleWidth:
- const void *double_ptr = &val;
- FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
- regs[floatReg + 1] = temp_double >> 32;
- regs[floatReg] = temp_double;
- break;
+ {
+ const void *double_ptr = &val;
+ FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
+ regs[floatReg + 1] = temp_double >> 32;
+ regs[floatReg] = 0x0000FFFF & temp_double;
+ break;
+ }
default:
panic("Attempted to read a %d bit floating point register!", width);
@@ -148,14 +155,6 @@ namespace MipsISA
void unserialize(Checkpoint *cp, const std::string &section);
};
- enum MiscFloatRegNums {
- FIR = NumFloatArchRegs,
- FCCR,
- FEXR,
- FENR,
- FCSR
- };
-
} // namespace MipsISA
#endif
diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc
new file mode 100644
index 000000000..e7455fdbf
--- /dev/null
+++ b/src/arch/mips/utility.cc
@@ -0,0 +1,202 @@
+/*
+ * 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: Korey Sewell
+ */
+
+#include "arch/mips/isa_traits.hh"
+#include "arch/mips/utility.hh"
+#include "config/full_system.hh"
+#include "cpu/static_inst.hh"
+#include "sim/serialize.hh"
+#include "base/bitfield.hh"
+
+using namespace MipsISA;
+using namespace std;
+
+uint64_t
+MipsISA::fpConvert(ConvertType cvt_type, double fp_val)
+{
+
+ switch (cvt_type)
+ {
+ case SINGLE_TO_DOUBLE:
+ {
+ double sdouble_val = fp_val;
+ void *sdouble_ptr = &sdouble_val;
+ uint64_t sdp_bits = *(uint64_t *) sdouble_ptr;
+ return sdp_bits;
+ }
+
+ case SINGLE_TO_WORD:
+ {
+ int32_t sword_val = (int32_t) fp_val;
+ void *sword_ptr = &sword_val;
+ uint64_t sword_bits= *(uint32_t *) sword_ptr;
+ return sword_bits;
+ }
+
+ case WORD_TO_SINGLE:
+ {
+ float wfloat_val = fp_val;
+ void *wfloat_ptr = &wfloat_val;
+ uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
+ return wfloat_bits;
+ }
+
+ case WORD_TO_DOUBLE:
+ {
+ double wdouble_val = fp_val;
+ void *wdouble_ptr = &wdouble_val;
+ uint64_t wdp_bits = *(uint64_t *) wdouble_ptr;
+ return wdp_bits;
+ }
+
+ default:
+ panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
+ return 0;
+ }
+}
+
+double
+MipsISA::roundFP(double val, int digits)
+{
+ double digit_offset = pow(10.0,digits);
+ val = val * digit_offset;
+ val = val + 0.5;
+ val = floor(val);
+ val = val / digit_offset;
+ return val;
+}
+
+double
+MipsISA::truncFP(double val)
+{
+ int trunc_val = (int) val;
+ return (double) trunc_val;
+}
+
+bool
+MipsISA::getCondCode(uint32_t fcsr, int cc_idx)
+{
+ int shift = (cc_idx == 0) ? 23 : cc_idx + 24;
+ bool cc_val = (fcsr >> shift) & 0x00000001;
+ return cc_val;
+}
+
+uint32_t
+MipsISA::genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val)
+{
+ int cc_idx = (cc_num == 0) ? 23 : cc_num + 24;
+
+ fcsr = bits(fcsr, 31, cc_idx + 1) << cc_idx + 1 |
+ cc_val << cc_idx |
+ bits(fcsr, cc_idx - 1, 0);
+
+ return fcsr;
+}
+
+uint32_t
+MipsISA::genInvalidVector(uint32_t fcsr_bits)
+{
+ //Set FCSR invalid in "flag" field
+ int invalid_offset = Invalid + Flag_Field;
+ fcsr_bits = fcsr_bits | (1 << invalid_offset);
+
+ //Set FCSR invalid in "cause" flag
+ int cause_offset = Invalid + Cause_Field;
+ fcsr_bits = fcsr_bits | (1 << cause_offset);
+
+ return fcsr_bits;
+}
+
+bool
+MipsISA::isNan(void *val_ptr, int size)
+{
+ switch (size)
+ {
+ case 32:
+ {
+ uint32_t val_bits = *(uint32_t *) val_ptr;
+ return (bits(val_bits, 30, 23) == 0xFF);
+ }
+
+ case 64:
+ {
+ uint64_t val_bits = *(uint64_t *) val_ptr;
+ return (bits(val_bits, 62, 52) == 0x7FF);
+ }
+
+ default:
+ panic("Type unsupported. Size mismatch\n");
+ }
+}
+
+
+bool
+MipsISA::isQnan(void *val_ptr, int size)
+{
+ switch (size)
+ {
+ case 32:
+ {
+ uint32_t val_bits = *(uint32_t *) val_ptr;
+ return (bits(val_bits, 30, 22) == 0x1FE);
+ }
+
+ case 64:
+ {
+ uint64_t val_bits = *(uint64_t *) val_ptr;
+ return (bits(val_bits, 62, 51) == 0xFFE);
+ }
+
+ default:
+ panic("Type unsupported. Size mismatch\n");
+ }
+}
+
+bool
+MipsISA::isSnan(void *val_ptr, int size)
+{
+ switch (size)
+ {
+ case 32:
+ {
+ uint32_t val_bits = *(uint32_t *) val_ptr;
+ return (bits(val_bits, 30, 22) == 0x1FF);
+ }
+
+ case 64:
+ {
+ uint64_t val_bits = *(uint64_t *) val_ptr;
+ return (bits(val_bits, 62, 51) == 0xFFF);
+ }
+
+ default:
+ panic("Type unsupported. Size mismatch\n");
+ }
+}
diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh
index 5c7dc3ea4..c5c69ddcd 100644
--- a/src/arch/mips/utility.hh
+++ b/src/arch/mips/utility.hh
@@ -39,6 +39,19 @@
namespace MipsISA {
+ //Floating Point Utility Functions
+ uint64_t fpConvert(ConvertType cvt_type, double fp_val);
+ double roundFP(double val, int digits);
+ double truncFP(double val);
+
+ bool getCondCode(uint32_t fcsr, int cc);
+ uint32_t genCCVector(uint32_t fcsr, int num, uint32_t cc_val);
+ uint32_t genInvalidVector(uint32_t fcsr);
+
+ bool isNan(void *val_ptr, int size);
+ bool isQnan(void *val_ptr, int size);
+ bool isSnan(void *val_ptr, int size);
};
+
#endif
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 57b4d4d86..2af242bd8 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -249,7 +249,7 @@ void SparcFault::invoke(ThreadContext * tc)
void TrapInstruction::invoke(ThreadContext * tc)
{
- tc->syscall(syscall_num);
+ // Should be handled in ISA.
}
#endif
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 762de243a..40afb3722 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -48,7 +48,7 @@ output header {{
output decoder {{
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
-#include "cpu/exec_context.hh" // for Jump::branchTarget()
+#include "cpu/thread_context.hh" // for Jump::branchTarget()
#include <math.h>
#if defined(linux)
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 633c202ca..75f01e038 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -31,56 +31,16 @@
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
-#include "arch/sparc/linux/process.hh"
-#include "arch/sparc/solaris/process.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
#include "mem/page_table.hh"
#include "mem/translating_port.hh"
-#include "sim/builder.hh"
#include "sim/system.hh"
using namespace std;
using namespace SparcISA;
-SparcLiveProcess *
-SparcLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
- int stdout_fd, int stderr_fd, std::string executable,
- std::vector<std::string> &argv, std::vector<std::string> &envp)
-{
- SparcLiveProcess *process = NULL;
-
- ObjectFile *objFile = createObjectFile(executable);
- if (objFile == NULL) {
- fatal("Can't load object file %s", executable);
- }
-
-
- if (objFile->getArch() != ObjectFile::SPARC)
- fatal("Object file with arch %x does not match architecture %x.",
- objFile->getArch(), ObjectFile::SPARC);
- switch (objFile->getOpSys()) {
- case ObjectFile::Linux:
- process = new SparcLinuxProcess(nm, objFile, system,
- stdin_fd, stdout_fd, stderr_fd,
- argv, envp);
- break;
-
-
- case ObjectFile::Solaris:
- process = new SparcSolarisProcess(nm, objFile, system,
- stdin_fd, stdout_fd, stderr_fd,
- argv, envp);
- break;
- default:
- fatal("Unknown/unsupported operating system.");
- }
-
- if (process == NULL)
- fatal("Unknown error creating process object.");
- return process;
-}
SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
@@ -322,61 +282,3 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
// num_processes++;
}
-
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcLiveProcess)
-
- VectorParam<string> cmd;
- Param<string> executable;
- Param<string> input;
- Param<string> output;
- VectorParam<string> env;
- SimObjectParam<System *> system;
-
-END_DECLARE_SIM_OBJECT_PARAMS(SparcLiveProcess)
-
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(SparcLiveProcess)
-
- INIT_PARAM(cmd, "command line (executable plus arguments)"),
- INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
- INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
- INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
- INIT_PARAM(env, "environment settings"),
- INIT_PARAM(system, "system")
-
-END_INIT_SIM_OBJECT_PARAMS(SparcLiveProcess)
-
-
-CREATE_SIM_OBJECT(SparcLiveProcess)
-{
- string in = input;
- string out = output;
-
- // initialize file descriptors to default: same as simulator
- int stdin_fd, stdout_fd, stderr_fd;
-
- if (in == "stdin" || in == "cin")
- stdin_fd = STDIN_FILENO;
- else
- stdin_fd = Process::openInputFile(input);
-
- if (out == "stdout" || out == "cout")
- stdout_fd = STDOUT_FILENO;
- else if (out == "stderr" || out == "cerr")
- stdout_fd = STDERR_FILENO;
- else
- stdout_fd = Process::openOutputFile(out);
-
- stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
-
- return SparcLiveProcess::create(getInstanceName(), system,
- stdin_fd, stdout_fd, stderr_fd,
- (string)executable == "" ? cmd[0] : executable,
- cmd, env);
-}
-
-
-REGISTER_SIM_OBJECT("SparcLiveProcess", SparcLiveProcess)
-
-
diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh
index db5e64352..7ba8d7109 100644
--- a/src/arch/sparc/process.hh
+++ b/src/arch/sparc/process.hh
@@ -65,15 +65,6 @@ class SparcLiveProcess : public LiveProcess
void startup();
public:
- // this function is used to create the LiveProcess object, since
- // we can't tell which subclass of LiveProcess to use until we
- // open and look at the object file.
- static SparcLiveProcess *create(const std::string &nm,
- System *_system,
- int stdin_fd, int stdout_fd, int stderr_fd,
- std::string executable,
- std::vector<std::string> &argv,
- std::vector<std::string> &envp);
void argsInit(int intSize, int pageSize);
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index aaf1fcf24..cbeb3c7b9 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -61,8 +61,7 @@ namespace SparcISA
const int HprStart = 64;
const int MiscStart = 96;
-
- const uint64_t Bit64 = 0x8000000000000000;
+ const uint64_t Bit64 = (1ULL << 63);
class IntRegFile
{
@@ -245,17 +244,22 @@ namespace SparcISA
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
+
+ uint32_t result32;
+ uint64_t result64;
switch(width)
{
case SingleWidth:
- uint32_t result32 = gtoh((uint32_t)val);
+ result32 = gtoh((uint32_t)val);
memcpy(regSpace + 4 * floatReg, &result32, width);
+ break;
case DoubleWidth:
- uint64_t result64 = gtoh((uint64_t)val);
+ result64 = gtoh((uint64_t)val);
memcpy(regSpace + 4 * floatReg, &result64, width);
+ break;
case QuadWidth:
- uint64_t result128 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result128, width);
+ panic("Quad width FP not implemented.");
+ break;
default:
panic("Attempted to read a %d bit floating point register!", width);
}
@@ -267,17 +271,21 @@ namespace SparcISA
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
+ uint32_t result32;
+ uint64_t result64;
switch(width)
{
case SingleWidth:
- uint32_t result32 = gtoh((uint32_t)val);
+ result32 = gtoh((uint32_t)val);
memcpy(regSpace + 4 * floatReg, &result32, width);
+ break;
case DoubleWidth:
- uint64_t result64 = gtoh((uint64_t)val);
+ result64 = gtoh((uint64_t)val);
memcpy(regSpace + 4 * floatReg, &result64, width);
+ break;
case QuadWidth:
- uint64_t result128 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result128, width);
+ panic("Quad width FP not implemented.");
+ break;
default:
panic("Attempted to read a %d bit floating point register!", width);
}
diff --git a/src/base/statistics.cc b/src/base/statistics.cc
index 03c6b5196..2acef83c5 100644
--- a/src/base/statistics.cc
+++ b/src/base/statistics.cc
@@ -43,7 +43,6 @@
#include "base/time.hh"
#include "base/trace.hh"
#include "base/stats/statdb.hh"
-#include "config/stats_binning.hh"
using namespace std;
@@ -174,12 +173,6 @@ FormulaBase::size() const
return root->size();
}
-bool
-FormulaBase::binned() const
-{
- return root && root->binned();
-}
-
void
FormulaBase::reset()
{
@@ -238,33 +231,6 @@ Formula::operator+=(Temp r)
return *this;
}
-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
check()
{
@@ -287,13 +253,6 @@ check()
Database::stats().sort(StatData::less);
-#if STATS_BINNING
- if (MainBin::curBin() == NULL) {
- static MainBin mainBin("main bin");
- mainBin.activate();
- }
-#endif
-
if (i == end)
return;
@@ -313,39 +272,14 @@ CallbackQueue resetQueue;
void
reset()
{
- // reset non-binned stats
Database::stat_list_t::iterator i = Database::stats().begin();
Database::stat_list_t::iterator end = Database::stats().end();
while (i != end) {
StatData *data = *i;
- if (!data->binned())
- data->reset();
+ data->reset();
++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;
-
resetQueue.process();
}
diff --git a/src/base/statistics.hh b/src/base/statistics.hh
index 84a323071..59f219c07 100644
--- a/src/base/statistics.hh
+++ b/src/base/statistics.hh
@@ -60,11 +60,9 @@
#include "base/intmath.hh"
#include "base/refcnt.hh"
#include "base/str.hh"
-#include "base/stats/bin.hh"
#include "base/stats/flags.hh"
#include "base/stats/visit.hh"
#include "base/stats/types.hh"
-#include "config/stats_binning.hh"
#include "sim/host.hh"
class Callback;
@@ -103,11 +101,6 @@ struct StatData
virtual ~StatData();
/**
- * @return true if the stat is binned.
- */
- virtual bool binned() const = 0;
-
- /**
* Reset the corresponding stat to the default state.
*/
virtual void reset() = 0;
@@ -160,7 +153,6 @@ class ScalarStatData : public ScalarData
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(); }
@@ -203,7 +195,6 @@ class VectorStatData : public VectorData
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(); }
@@ -261,7 +252,6 @@ class DistStatData : public DistData
public:
DistStatData(Stat &stat) : s(stat) {}
- virtual bool binned() const { return s.binned(); }
virtual bool check() const { return s.check(); }
virtual void reset() { s.reset(); }
virtual bool zero() const { return s.zero(); }
@@ -300,12 +290,10 @@ class VectorDistStatData : public VectorDistData
{
protected:
Stat &s;
- typedef typename Stat::bin_t bin_t;
public:
VectorDistStatData(Stat &stat) : s(stat) {}
- virtual bool binned() const { return bin_t::binned; }
virtual bool check() const { return s.check(); }
virtual void reset() { s.reset(); }
virtual size_t size() const { return s.size(); }
@@ -342,12 +330,10 @@ class Vector2dStatData : public Vector2dData
{
protected:
Stat &s;
- typedef typename Stat::bin_t bin_t;
public:
Vector2dStatData(Stat &stat) : s(stat) {}
- virtual bool binned() const { return bin_t::binned; }
virtual bool check() const { return s.check(); }
virtual void reset() { s.reset(); }
virtual bool zero() const { return s.zero(); }
@@ -359,7 +345,6 @@ class Vector2dStatData : public Vector2dData
}
};
-
class DataAccess
{
protected:
@@ -615,22 +600,16 @@ struct StatStor
* 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.
- * @todo add lateny to the stat and fix binning.
*/
struct AvgStor
{
public:
/** The paramaters for this storage type */
- struct Params
- {
- /**
- * The current count. We stash this here because the current
- * value is not a binned value.
- */
- Counter current;
- };
+ struct Params { };
private:
+ /** The current count. */
+ Counter current;
/** The total count for all cycles. */
mutable Result total;
/** The cycle that current last changed. */
@@ -640,7 +619,7 @@ struct AvgStor
/**
* Build and initializes this stat storage.
*/
- AvgStor(Params &p) : total(0), last(0) { p.current = Counter(); }
+ AvgStor(Params &p) : current(0), total(0), last(0) { }
/**
* Set the current count to the one provided, update the total and last
@@ -649,9 +628,9 @@ struct AvgStor
* @param p The parameters for this storage.
*/
void set(Counter val, Params &p) {
- total += p.current * (curTick - last);
+ total += current * (curTick - last);
last = curTick;
- p.current = val;
+ current = val;
}
/**
@@ -659,21 +638,21 @@ struct AvgStor
* @param val The amount to increment.
* @param p The parameters for this storage.
*/
- void inc(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.
*/
- void dec(Counter val, Params &p) { set(p.current - val, p); }
+ 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.
*/
- Counter value(const Params &p) const { return p.current; }
+ Counter value(const Params &p) const { return current; }
/**
* Return the current average.
@@ -682,9 +661,9 @@ struct AvgStor
*/
Result result(const Params &p) const
{
- total += p.current * (curTick - last);
+ total += current * (curTick - last);
last = curTick;
- return (Result)(total + p.current) / (Result)(curTick + 1);
+ return (Result)(total + current) / (Result)(curTick + 1);
}
/**
@@ -704,39 +683,53 @@ struct AvgStor
/**
* Implementation of a scalar stat. The type of stat is determined by the
- * Storage template. The storage for this stat is held within the Bin class.
- * This allows for breaking down statistics across multiple bins easily.
+ * Storage template.
*/
-template <class Storage, class Bin>
+template <class Stor>
class ScalarBase : public DataAccess
{
public:
+ typedef Stor Storage;
+
/** Define the params of the storage class. */
- typedef typename Storage::Params params_t;
- /** Define the bin type. */
- typedef typename Bin::template Bin<Storage> bin_t;
+ typedef typename Storage::Params Params;
protected:
- /** The bin of this stat. */
- bin_t bin;
+ /** The storage of this stat. */
+ char storage[sizeof(Storage)];
+
/** The parameters for this stat. */
- params_t params;
+ Params params;
protected:
/**
- * Retrieve the storage from the bin.
- * @return The storage object for this stat.
+ * Retrieve the storage.
+ * @param index The vector index to access.
+ * @return The storage object at the given index.
*/
- Storage *data() { return bin.data(params); }
+ Storage *
+ data()
+ {
+ return reinterpret_cast<Storage *>(storage);
+ }
+
/**
- * Retrieve a const pointer to the storage from the bin.
- * @return A const pointer to the storage object for this stat.
+ * 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.
*/
- const Storage *data() const
+ const Storage *
+ data() const
{
- bin_t *_bin = const_cast<bin_t *>(&bin);
- params_t *_params = const_cast<params_t *>(&params);
- return _bin->data(*_params);
+ return reinterpret_cast<const Storage *>(storage);
+ }
+
+ void
+ doInit()
+ {
+ new (storage) Storage(params);
+ setInit();
}
public:
@@ -751,9 +744,7 @@ class ScalarBase : public DataAccess
* Create and initialize this stat, register it with the database.
*/
ScalarBase()
- {
- bin.init(params);
- }
+ { }
public:
// Common operators for stats
@@ -802,18 +793,13 @@ class ScalarBase : public DataAccess
* @return 1.
*/
size_t size() const { return 1; }
- /**
- * Return true if stat is binned.
- *@return True is stat is binned.
- */
- bool binned() const { return bin_t::binned; }
- bool check() const { return bin.initialized(); }
+ bool check() const { return true; }
/**
* Reset stat value to default
*/
- void reset() { bin.reset(); }
+ void reset() { data()->reset(); }
Counter value() { return data()->value(params); }
@@ -829,7 +815,6 @@ class ProxyData : public ScalarData
{
public:
virtual void visit(Visit &visitor) { visitor.visit(*this); }
- virtual bool binned() const { return false; }
virtual std::string str() const { return to_string(value()); }
virtual size_t size() const { return 1; }
virtual bool zero() const { return value() == 0; }
@@ -891,7 +876,6 @@ class ValueBase : public DataAccess
Result total() const { return proxy->total(); };
size_t size() const { return proxy->size(); }
- bool binned() const { return proxy->binned(); }
std::string str() const { return proxy->str(); }
bool zero() const { return proxy->zero(); }
bool check() const { return proxy != NULL; }
@@ -903,195 +887,62 @@ class ValueBase : public DataAccess
// Vector Statistics
//
//////////////////////////////////////////////////////////////////////
-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);
/**
* A proxy class to access the stat at a given index in a VectorBase stat.
* Behaves like a ScalarBase.
*/
-template <class Storage, class Bin>
+template <class Stat>
class ScalarProxy
{
- 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;
-
private:
- /** Pointer to the bin in the parent VectorBase. */
- bin_t *bin;
- /** Pointer to the params in the parent VectorBase. */
- params_t *params;
+ /** Pointer to the parent Vector. */
+ Stat *stat;
+
/** The index to access in the parent VectorBase. */
int index;
- /** 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);
- }
public:
/**
* Return the current value of this stat as its base type.
* @return The current value.
*/
- Counter value() const { return data()->value(*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.
*/
- Result result() const { return data()->result(*params); }
+ Result result() const { return stat->data(index)->result(stat->params); }
public:
/**
* Create and initialize this proxy, do not register it with the database.
- * @param b The bin to use.
* @param p The params to use.
* @param i The index to access.
*/
- ScalarProxy(bin_t &b, params_t &p, int i, void *s)
- : bin(&b), params(&p), index(i), stat(s) {}
+ 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) {}
+ : 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) {
- bin = sp.bin;
- params = sp.params;
- index = sp.index;
stat = sp.stat;
+ index = sp.index;
return *this;
}
@@ -1101,12 +952,12 @@ class ScalarProxy
* Increment the stat by 1. This calls the associated storage object inc
* function.
*/
- void operator++() { data()->inc(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--() { data()->dec(1, *params); }
+ void operator--() { stat->data(index)->dec(1, stat->params); }
/** Increment the stat by 1. */
void operator++(int) { ++*this; }
@@ -1119,7 +970,7 @@ class ScalarProxy
* @param v The new value.
*/
template <typename U>
- void operator=(const U &v) { data()->set(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
@@ -1127,7 +978,7 @@ class ScalarProxy
* @param v The value to add.
*/
template <typename U>
- void operator+=(const U &v) { data()->inc(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
@@ -1135,7 +986,7 @@ class ScalarProxy
* @param v The value to substract.
*/
template <typename U>
- void operator-=(const U &v) { data()->dec(v, *params); }
+ void operator-=(const U &v) { stat->data(index)->dec(v, stat->params); }
/**
* Return the number of elements, always 1 for a scalar.
@@ -1144,192 +995,356 @@ class ScalarProxy
size_t size() const { return 1; }
/**
- * Return true if stat is binned.
- *@return false since Proxies aren't printed/binned
- */
- bool binned() const { return false; }
-
- /**
* This stat has no state. Nothing to reset
*/
void reset() { }
public:
- const StatData *statData() const { return getStatData(stat); }
- std::string str() const
+ std::string
+ str() const
{
- return csprintf("%s[%d]", this->statData()->name, index);
+ return csprintf("%s[%d]", stat->str(), index);
}
};
-template <class Storage, class Bin>
-inline ScalarProxy<Storage, Bin>
-VectorBase<Storage, Bin>::operator[](int index)
+/**
+ * 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
{
- assert (index >= 0 && index < size());
- return ScalarProxy<Storage, Bin>(bin, params, index, this);
-}
+ public:
+ typedef Stor Storage;
+
+ /** Define the params of the storage class. */
+ typedef typename Storage::Params Params;
-template <class Storage, class Bin>
-class VectorProxy;
+ /** Proxy type */
+ typedef ScalarProxy<VectorBase<Storage> > Proxy;
-template <class Storage, class Bin>
-class Vector2dBase : public DataAccess
-{
- public:
- typedef typename Storage::Params params_t;
- typedef typename Bin::template VectorBin<Storage> bin_t;
+ friend class ScalarProxy<VectorBase<Storage> >;
protected:
- size_t x;
- size_t y;
- bin_t bin;
- params_t params;
+ /** The storage of this stat. */
+ Storage *storage;
+ size_t _size;
+
+ /** The parameters for this stat. */
+ Params params;
protected:
- Storage *data(int index) { return bin.data(index, params); }
- const Storage *data(int index) const
+ /**
+ * 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)
{
- bin_t *_bin = const_cast<bin_t *>(&bin);
- params_t *_params = const_cast<params_t *>(&params);
- return _bin->data(index, *_params);
+ 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:
- Vector2dBase() {}
+ void value(VCounter &vec) const
+ {
+ vec.resize(size());
+ for (int i = 0; i < size(); ++i)
+ vec[i] = data(i)->value(params);
+ }
- void update(Vector2dData *data)
+ /**
+ * 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
{
- int size = this->size();
- data->cvec.resize(size);
- for (int i = 0; i < size; ++i)
- data->cvec[i] = this->data(i)->value(params);
+ vec.resize(size());
+ for (int i = 0; i < size(); ++i)
+ vec[i] = data(i)->result(params);
}
- std::string ysubname(int i) const { return (*this->y_subnames)[i]; }
+ /**
+ * 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; }
- friend class VectorProxy<Storage, Bin>;
- VectorProxy<Storage, Bin> operator[](int index);
+ bool
+ zero() const
+ {
+ for (int i = 0; i < size(); ++i)
+ if (data(i)->zero())
+ return false;
+ return true;
+ }
- size_t size() const { return bin.size(); }
- bool zero() const { return data(0)->value(params) == 0.0; }
+ 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);
+ }
/**
- * Reset stat value to default
+ * Return a reference (ScalarProxy) to the stat at the given index.
+ * @param index The vector index to access.
+ * @return A reference of the stat.
*/
- void reset() { bin.reset(); }
+ Proxy
+ operator[](int index)
+ {
+ assert (index >= 0 && index < size());
+ return Proxy(this, index);
+ }
- bool check() { return bin.initialized(); }
+ void update(StatData *data) {}
};
-template <class Storage, class Bin>
+template <class Stat>
class VectorProxy
{
- public:
- typedef typename Storage::Params params_t;
- typedef typename Bin::template VectorBin<Storage> bin_t;
-
private:
- bin_t *bin;
- params_t *params;
+ Stat *stat;
int offset;
int len;
- void *stat;
private:
- mutable VResult *vec;
+ mutable VResult vec;
- Storage *data(int index) {
+ typename Stat::Storage *
+ data(int index)
+ {
assert(index < len);
- return bin->data(offset + index, *params);
+ return stat->data(offset + 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(offset + index, *_params);
+ const typename Stat::Storage *
+ data(int index) const
+ {
+ assert(index < len);
+ return const_cast<Stat *>(stat)->data(offset + index);
}
public:
- const VResult &result() const {
- if (vec)
- vec->resize(size());
- else
- vec = new VResult(size());
+ const VResult &
+ result() const
+ {
+ vec.resize(size());
for (int i = 0; i < size(); ++i)
- (*vec)[i] = data(i)->result(*params);
+ vec[i] = data(i)->result(stat->params);
- return *vec;
+ return vec;
}
- Result total() const {
- Result total = 0.0;
+ Result
+ total() const
+ {
+ Result total = 0;
for (int i = 0; i < size(); ++i)
- total += data(i)->result(*params);
+ total += data(i)->result(stat->params);
return total;
}
public:
- 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)
+ VectorProxy(Stat *s, int o, int l)
+ : stat(s), offset(o), len(l)
{
}
VectorProxy(const VectorProxy &sp)
- : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len),
- stat(sp.stat), vec(NULL)
- {
- }
-
- ~VectorProxy()
+ : stat(sp.stat), offset(sp.offset), len(sp.len)
{
- if (vec)
- delete vec;
}
- const VectorProxy &operator=(const VectorProxy &sp)
+ const VectorProxy &
+ operator=(const VectorProxy &sp)
{
- bin = sp.bin;
- params = sp.params;
+ stat = sp.stat;
offset = sp.offset;
len = sp.len;
- stat = sp.stat;
- if (vec)
- delete vec;
- vec = NULL;
return *this;
}
- ScalarProxy<Storage, Bin> operator[](int index)
+ ScalarProxy<Stat> operator[](int index)
{
assert (index >= 0 && index < size());
- return ScalarProxy<Storage, Bin>(*bin, *params, offset + index, stat);
+ return ScalarProxy<Stat>(stat, offset + index);
}
size_t size() const { return len; }
/**
- * Return true if stat is binned.
- *@return false since Proxies aren't printed/binned
- */
- bool binned() const { return false; }
-
- /**
* This stat has no state. Nothing to reset.
*/
void reset() { }
};
-template <class Storage, class Bin>
-inline VectorProxy<Storage, Bin>
-Vector2dBase<Storage, Bin>::operator[](int index)
+template <class Stor>
+class Vector2dBase : public DataAccess
{
- int offset = index * y;
- assert (index >= 0 && offset < size());
- return VectorProxy<Storage, Bin>(bin, params, offset, y, this);
-}
+ 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;
+ }
+};
//////////////////////////////////////////////////////////////////////
//
@@ -1376,14 +1391,8 @@ struct DistStor
VCounter cvec;
public:
- /**
- * Construct this storage with the supplied params.
- * @param params The parameters.
- */
DistStor(const Params &params)
- : min_val(INT_MAX), max_val(INT_MIN), underflow(Counter()),
- overflow(Counter()), sum(Counter()), squares(Counter()),
- samples(Counter()), cvec(params.size)
+ : cvec(params.size)
{
reset();
}
@@ -1618,36 +1627,46 @@ struct AvgFancy
* Implementation of a distribution stat. The type of distribution is
* determined by the Storage template. @sa ScalarBase
*/
-template <class Storage, class Bin>
+template <class Stor>
class DistBase : public DataAccess
{
public:
+ typedef Stor Storage;
/** Define the params of the storage class. */
- typedef typename Storage::Params params_t;
- /** Define the bin type. */
- typedef typename Bin::template Bin<Storage> bin_t;
+ typedef typename Storage::Params Params;
protected:
- /** The bin of this stat. */
- bin_t bin;
+ /** The storage for this stat. */
+ char storage[sizeof(Storage)];
+
/** The parameters for this stat. */
- params_t params;
+ Params params;
protected:
/**
- * Retrieve the storage from the bin.
+ * Retrieve the storage.
* @return The storage object for this stat.
*/
- Storage *data() { return bin.data(params); }
+ Storage *data()
+ {
+ return reinterpret_cast<Storage *>(storage);
+ }
+
/**
- * Retrieve a const pointer to the storage from the bin.
+ * Retrieve a const pointer to the storage.
* @return A const pointer to the storage object for this stat.
*/
- const Storage *data() const
+ const Storage *
+ data() const
{
- bin_t *_bin = const_cast<bin_t *>(&bin);
- params_t *_params = const_cast<params_t *>(&params);
- return _bin->data(*_params);
+ return reinterpret_cast<const Storage *>(storage);
+ }
+
+ void
+ doInit()
+ {
+ new (storage) Storage(params);
+ setInit();
}
public:
@@ -1678,65 +1697,122 @@ class DistBase : public DataAccess
base->data.fancy = Storage::fancy;
data()->update(&(base->data), params);
}
- /**
- * @return True is stat is binned.
- */
- bool binned() const { return bin_t::binned; }
+
/**
* Reset stat value to default
*/
- void reset()
+ void
+ reset()
{
- bin.reset();
+ data()->reset();
}
- bool check() { return bin.initialized(); }
+ bool
+ check()
+ {
+ return true;
+ }
};
-template <class Storage, class Bin>
+template <class Stat>
class DistProxy;
-template <class Storage, class Bin>
+template <class Stor>
class VectorDistBase : public DataAccess
{
public:
- typedef typename Storage::Params params_t;
- typedef typename Bin::template VectorBin<Storage> bin_t;
+ typedef Stor Storage;
+ typedef typename Storage::Params Params;
+ typedef DistProxy<VectorDistBase<Storage> > Proxy;
+ friend class DistProxy<VectorDistBase<Storage> >;
protected:
- bin_t bin;
- params_t params;
+ Storage *storage;
+ size_t _size;
+ Params params;
protected:
- Storage *data(int index) { return bin.data(index, params); }
- const Storage *data(int index) const
+ Storage *
+ data(int index)
+ {
+ return &storage[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);
+ 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:
- VectorDistBase() {}
+ VectorDistBase()
+ : storage(NULL)
+ {}
- friend class DistProxy<Storage, Bin>;
- DistProxy<Storage, Bin> operator[](int index);
- const DistProxy<Storage, Bin> operator[](int index) const;
+ ~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
+ }
- 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; }
/**
* Reset stat value to default
*/
- void reset() { bin.reset(); }
+ void
+ reset()
+ {
+ for (int i = 0; i < size(); ++i)
+ data(i)->reset();
+ }
+
+ bool
+ check()
+ {
+ return storage != NULL;
+ }
- bool check() { return bin.initialized(); }
- void update(VectorDistData *base)
+ void
+ update(VectorDistData *base)
{
int size = this->size();
base->data.resize(size);
@@ -1747,75 +1823,75 @@ class VectorDistBase : public DataAccess
}
};
-template <class Storage, class Bin>
+template <class Stat>
class DistProxy
{
- public:
- typedef typename Storage::Params params_t;
- typedef typename Bin::template Bin<Storage> bin_t;
- typedef VectorDistBase<Storage, Bin> base_t;
-
private:
- union {
- base_t *stat;
- const base_t *cstat;
- };
+ Stat *stat;
int index;
protected:
- Storage *data() { return stat->data(index); }
- const Storage *data() const { return cstat->data(index); }
+ typename Stat::Storage *data() { return stat->data(index); }
+ const typename Stat::Storage *data() const { return stat->data(index); }
public:
- DistProxy(const VectorDistBase<Storage, Bin> &s, int i)
- : cstat(&s), index(i) {}
+ DistProxy(Stat *s, int i)
+ : stat(s), index(i)
+ {}
+
DistProxy(const DistProxy &sp)
- : cstat(sp.cstat), index(sp.index) {}
- const DistProxy &operator=(const DistProxy &sp) {
- cstat = sp.cstat; index = sp.index; return *this;
+ : stat(sp.stat), index(sp.index)
+ {}
+
+ const DistProxy &operator=(const DistProxy &sp)
+ {
+ stat = sp.stat;
+ index = sp.index;
+ return *this;
}
public:
template <typename U>
- void sample(const U &v, int n = 1) { data()->sample(v, n, cstat->params); }
+ 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);
+ }
- 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; }
/**
* Proxy has no state. Nothing to reset.
*/
void reset() { }
};
-template <class Storage, class Bin>
-inline DistProxy<Storage, Bin>
-VectorDistBase<Storage, Bin>::operator[](int index)
+template <class Storage>
+inline typename VectorDistBase<Storage>::Proxy
+VectorDistBase<Storage>::operator[](int index)
{
assert (index >= 0 && index < size());
- 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);
+ return typename VectorDistBase<Storage>::Proxy(this, index);
}
#if 0
-template <class Storage, class Bin>
+template <class Storage>
Result
-VectorDistBase<Storage, Bin>::total(int index) const
+VectorDistBase<Storage>::total(int index) const
{
int total = 0;
- for (int i=0; i < x_size(); ++i) {
- total += data(i)->result(*params);
+ for (int i = 0; i < x_size(); ++i) {
+ total += data(i)->result(stat->params);
}
}
#endif
@@ -1848,11 +1924,6 @@ class Node : public RefCounted
* @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 = 0;
/**
*
@@ -1879,11 +1950,6 @@ class ScalarStatNode : public Node
virtual Result total() const { return data->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(); }
/**
*
@@ -1891,34 +1957,45 @@ class ScalarStatNode : public Node
virtual std::string str() const { return data->name; }
};
-template <class Storage, class Bin>
+template <class Stat>
class ScalarProxyNode : public Node
{
private:
- const ScalarProxy<Storage, Bin> proxy;
+ const ScalarProxy<Stat> proxy;
mutable VResult vresult;
public:
- ScalarProxyNode(const ScalarProxy<Storage, Bin> &p)
- : proxy(p), vresult(1) { }
- virtual const VResult &result() const
+ ScalarProxyNode(const ScalarProxy<Stat> &p)
+ : proxy(p), vresult(1)
+ { }
+
+ virtual const VResult &
+ result() const
{
vresult[0] = proxy.result();
return vresult;
}
- 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 proxy.binned(); }
+ virtual Result
+ total() const
+ {
+ return proxy.result();
+ }
+
+ virtual size_t
+ size() const
+ {
+ return 1;
+ }
/**
*
*/
- virtual std::string str() const { return proxy.str(); }
+ virtual std::string
+ str() const
+ {
+ return proxy.str();
+ }
};
class VectorStatNode : public Node
@@ -1932,11 +2009,6 @@ class VectorStatNode : public Node
virtual Result total() const { return data->total(); };
virtual size_t size() const { return data->size(); }
- /**
- * 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 data->name; }
};
@@ -1952,13 +2024,6 @@ class ConstNode : public Node
const VResult &result() const { return vresult; }
virtual Result total() const { return vresult[0]; };
virtual size_t size() const { return 1; }
-
- /**
- * 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 to_string(vresult[0]); }
};
@@ -2032,11 +2097,6 @@ class UnaryNode : public Node
}
virtual size_t size() const { return l->size(); }
- /**
- * 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
{
@@ -2103,11 +2163,6 @@ class BinaryNode : public Node
return ls;
}
}
- /**
- * 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
{
@@ -2156,11 +2211,6 @@ class SumNode : public Node
}
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
{
@@ -2176,40 +2226,24 @@ class SumNode : public Node
//////////////////////////////////////////////////////////////////////
/**
* @defgroup VisibleStats "Statistic Types"
- * 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.
+ * These are the statistics that are used in the simulator.
* @{
*/
/**
- * 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
-
-/**
* This is a simple scalar statistic, like a counter.
* @sa Stat, ScalarBase, StatStor
*/
-template <class Bin = DefaultBin>
-class Scalar
- : public Wrap<Scalar<Bin>,
- ScalarBase<StatStor, Bin>,
- ScalarStatData>
+template<int N = 0>
+class Scalar : public Wrap<Scalar<N>, ScalarBase<StatStor>, ScalarStatData>
{
public:
/** The base implementation. */
- typedef ScalarBase<StatStor, Bin> Base;
+ typedef ScalarBase<StatStor> Base;
Scalar()
{
- this->setInit();
+ this->doInit();
}
/**
@@ -2221,10 +2255,7 @@ class Scalar
void operator=(const U &v) { Base::operator=(v); }
};
-class Value
- : public Wrap<Value,
- ValueBase,
- ScalarStatData>
+class Value : public Wrap<Value, ValueBase, ScalarStatData>
{
public:
/** The base implementation. */
@@ -2249,19 +2280,16 @@ class Value
* A stat that calculates the per cycle average of a value.
* @sa Stat, ScalarBase, AvgStor
*/
-template <class Bin = DefaultBin>
-class Average
- : public Wrap<Average<Bin>,
- ScalarBase<AvgStor, Bin>,
- ScalarStatData>
+template<int N = 0>
+class Average : public Wrap<Average<N>, ScalarBase<AvgStor>, ScalarStatData>
{
public:
/** The base implementation. */
- typedef ScalarBase<AvgStor, Bin> Base;
+ typedef ScalarBase<AvgStor> Base;
Average()
{
- this->setInit();
+ this->doInit();
}
/**
@@ -2277,15 +2305,12 @@ class Average
* A vector of scalar stats.
* @sa Stat, VectorBase, StatStor
*/
-template <class Bin = DefaultBin>
-class Vector
- : public WrapVec<Vector<Bin>,
- VectorBase<StatStor, Bin>,
- VectorStatData>
+template<int N = 0>
+class Vector : public WrapVec<Vector<N>, VectorBase<StatStor>, VectorStatData>
{
public:
/** The base implementation. */
- typedef ScalarBase<StatStor, Bin> Base;
+ typedef ScalarBase<StatStor> Base;
/**
* Set this vector to have the given size.
@@ -2293,9 +2318,7 @@ class Vector
* @return A reference to this stat.
*/
Vector &init(size_t size) {
- this->bin.init(size, this->params);
- this->setInit();
-
+ this->doInit(size);
return *this;
}
};
@@ -2304,11 +2327,9 @@ class Vector
* A vector of Average stats.
* @sa Stat, VectorBase, AvgStor
*/
-template <class Bin = DefaultBin>
+template<int N = 0>
class AverageVector
- : public WrapVec<AverageVector<Bin>,
- VectorBase<AvgStor, Bin>,
- VectorStatData>
+ : public WrapVec<AverageVector<N>, VectorBase<AvgStor>, VectorStatData>
{
public:
/**
@@ -2317,9 +2338,7 @@ class AverageVector
* @return A reference to this stat.
*/
AverageVector &init(size_t size) {
- this->bin.init(size, this->params);
- this->setInit();
-
+ this->doInit(size);
return *this;
}
};
@@ -2328,19 +2347,13 @@ class AverageVector
* A 2-Dimensional vecto of scalar stats.
* @sa Stat, Vector2dBase, StatStor
*/
-template <class Bin = DefaultBin>
+template<int N = 0>
class Vector2d
- : public WrapVec2d<Vector2d<Bin>,
- Vector2dBase<StatStor, Bin>,
- Vector2dStatData>
+ : public WrapVec2d<Vector2d<N>, Vector2dBase<StatStor>, Vector2dStatData>
{
public:
- 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();
-
+ Vector2d &init(size_t x, size_t y) {
+ this->doInit(x, y);
return *this;
}
};
@@ -2349,17 +2362,15 @@ class Vector2d
* A simple distribution stat.
* @sa Stat, DistBase, DistStor
*/
-template <class Bin = DefaultBin>
+template<int N = 0>
class Distribution
- : public Wrap<Distribution<Bin>,
- DistBase<DistStor, Bin>,
- DistStatData>
+ : public Wrap<Distribution<N>, DistBase<DistStor>, DistStatData>
{
public:
/** Base implementation. */
- typedef DistBase<DistStor, Bin> Base;
+ typedef DistBase<DistStor> Base;
/** The Parameter type. */
- typedef typename DistStor::Params Params;
+ typedef DistStor::Params Params;
public:
/**
@@ -2374,9 +2385,7 @@ class Distribution
this->params.max = max;
this->params.bucket_size = bkt;
this->params.size = (int)rint((max - min) / bkt + 1.0);
- this->bin.init(this->params);
- this->setInit();
-
+ this->doInit();
return *this;
}
};
@@ -2385,25 +2394,22 @@ class Distribution
* Calculates the mean and variance of all the samples.
* @sa Stat, DistBase, FancyStor
*/
-template <class Bin = DefaultBin>
+template<int N = 0>
class StandardDeviation
- : public Wrap<StandardDeviation<Bin>,
- DistBase<FancyStor, Bin>,
- DistStatData>
+ : public Wrap<StandardDeviation<N>, DistBase<FancyStor>, DistStatData>
{
public:
/** The base implementation */
- typedef DistBase<DistStor, Bin> Base;
+ typedef DistBase<DistStor> Base;
/** The parameter type. */
- typedef typename DistStor::Params Params;
+ typedef DistStor::Params Params;
public:
/**
* Construct and initialize this distribution.
*/
StandardDeviation() {
- this->bin.init(this->params);
- this->setInit();
+ this->doInit();
}
};
@@ -2411,17 +2417,15 @@ class StandardDeviation
* Calculates the per cycle mean and variance of the samples.
* @sa Stat, DistBase, AvgFancy
*/
-template <class Bin = DefaultBin>
+template<int N = 0>
class AverageDeviation
- : public Wrap<AverageDeviation<Bin>,
- DistBase<AvgFancy, Bin>,
- DistStatData>
+ : public Wrap<AverageDeviation<N>, DistBase<AvgFancy>, DistStatData>
{
public:
/** The base implementation */
- typedef DistBase<DistStor, Bin> Base;
+ typedef DistBase<DistStor> Base;
/** The parameter type. */
- typedef typename DistStor::Params Params;
+ typedef DistStor::Params Params;
public:
/**
@@ -2429,8 +2433,7 @@ class AverageDeviation
*/
AverageDeviation()
{
- this->bin.init(this->params);
- this->setInit();
+ this->doInit();
}
};
@@ -2438,17 +2441,17 @@ class AverageDeviation
* A vector of distributions.
* @sa Stat, VectorDistBase, DistStor
*/
-template <class Bin = DefaultBin>
+template<int N = 0>
class VectorDistribution
- : public WrapVec<VectorDistribution<Bin>,
- VectorDistBase<DistStor, Bin>,
+ : public WrapVec<VectorDistribution<N>,
+ VectorDistBase<DistStor>,
VectorDistStatData>
{
public:
/** The base implementation */
- typedef VectorDistBase<DistStor, Bin> Base;
+ typedef VectorDistBase<DistStor> Base;
/** The parameter type. */
- typedef typename DistStor::Params Params;
+ typedef DistStor::Params Params;
public:
/**
@@ -2464,9 +2467,7 @@ class VectorDistribution
this->params.max = max;
this->params.bucket_size = bkt;
this->params.size = (int)rint((max - min) / bkt + 1.0);
- this->bin.init(size, this->params);
- this->setInit();
-
+ this->doInit(size);
return *this;
}
};
@@ -2475,17 +2476,17 @@ class VectorDistribution
* This is a vector of StandardDeviation stats.
* @sa Stat, VectorDistBase, FancyStor
*/
-template <class Bin = DefaultBin>
+template<int N = 0>
class VectorStandardDeviation
- : public WrapVec<VectorStandardDeviation<Bin>,
- VectorDistBase<FancyStor, Bin>,
+ : public WrapVec<VectorStandardDeviation<N>,
+ VectorDistBase<FancyStor>,
VectorDistStatData>
{
public:
/** The base implementation */
- typedef VectorDistBase<FancyStor, Bin> Base;
+ typedef VectorDistBase<FancyStor> Base;
/** The parameter type. */
- typedef typename DistStor::Params Params;
+ typedef DistStor::Params Params;
public:
/**
@@ -2494,9 +2495,7 @@ class VectorStandardDeviation
* @return A reference to this distribution.
*/
VectorStandardDeviation &init(int size) {
- this->bin.init(size, this->params);
- this->setInit();
-
+ this->doInit(size);
return *this;
}
};
@@ -2505,17 +2504,17 @@ class VectorStandardDeviation
* This is a vector of AverageDeviation stats.
* @sa Stat, VectorDistBase, AvgFancy
*/
-template <class Bin = DefaultBin>
+template<int N = 0>
class VectorAverageDeviation
- : public WrapVec<VectorAverageDeviation<Bin>,
- VectorDistBase<AvgFancy, Bin>,
+ : public WrapVec<VectorAverageDeviation<N>,
+ VectorDistBase<AvgFancy>,
VectorDistStatData>
{
public:
/** The base implementation */
- typedef VectorDistBase<AvgFancy, Bin> Base;
+ typedef VectorDistBase<AvgFancy> Base;
/** The parameter type. */
- typedef typename DistStor::Params Params;
+ typedef DistStor::Params Params;
public:
/**
@@ -2524,9 +2523,7 @@ class VectorAverageDeviation
* @return A reference to this distribution.
*/
VectorAverageDeviation &init(int size) {
- this->bin.init(size, this->params);
- this->setInit();
-
+ this->doInit(size);
return *this;
}
};
@@ -2570,13 +2567,6 @@ class FormulaBase : public DataAccess
*/
size_t size() const;
- /**
- * Return true if Formula is binned. i.e. any of its children
- * nodes are binned
- * @return True if Formula is binned.
- */
- bool binned() const;
-
bool check() const { return true; }
/**
@@ -2615,7 +2605,6 @@ class FormulaStatData : public FormulaData
public:
FormulaStatData(Stat &stat) : s(stat) {}
- virtual bool binned() const { return s.binned(); }
virtual bool zero() const { return s.zero(); }
virtual void reset() { s.reset(); }
@@ -2682,7 +2671,6 @@ class FormulaNode : public Node
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(); }
- virtual bool binned() const { return formula.binned(); }
virtual std::string str() const { return formula.str(); }
};
@@ -2716,8 +2704,8 @@ class Temp
* Create a new ScalarStatNode.
* @param s The ScalarStat to place in a node.
*/
- template <class Bin>
- Temp(const Scalar<Bin> &s)
+ template <int N>
+ Temp(const Scalar<N> &s)
: node(new ScalarStatNode(s.statData())) { }
/**
@@ -2731,16 +2719,16 @@ class Temp
* 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 Average<N> &s)
: node(new ScalarStatNode(s.statData())) { }
/**
* Create a new VectorStatNode.
* @param s The VectorStat to place in a node.
*/
- template <class Bin>
- Temp(const Vector<Bin> &s)
+ template <int N>
+ Temp(const Vector<N> &s)
: node(new VectorStatNode(s.statData())) { }
/**
@@ -2753,9 +2741,9 @@ class Temp
* Create a new ScalarProxyNode.
* @param p The ScalarProxy to place in a node.
*/
- template <class Storage, class Bin>
- Temp(const ScalarProxy<Storage, Bin> &p)
- : node(new ScalarProxyNode<Storage, Bin>(p)) { }
+ template <class Stat>
+ Temp(const ScalarProxy<Stat> &p)
+ : node(new ScalarProxyNode<Stat>(p)) { }
/**
* Create a ConstNode
diff --git a/src/base/stats/mysql.cc b/src/base/stats/mysql.cc
index fa4bcd5ee..0fb31f4ce 100644
--- a/src/base/stats/mysql.cc
+++ b/src/base/stats/mysql.cc
@@ -158,14 +158,6 @@ MySqlRun::cleanup()
if (mysql.commit())
panic("could not commit transaction\n%s\n", mysql.error);
- 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);
-
mysql.query("DELETE events"
"FROM events"
"LEFT JOIN runs ON ev_run=rn_id"
@@ -309,52 +301,6 @@ SetupStat::setup()
return statid;
}
-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;
-}
-
InsertData::InsertData()
{
query = new char[maxsize + 1];
@@ -384,7 +330,7 @@ InsertData::flush()
size = 0;
first = true;
strcpy(query, "INSERT INTO "
- "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_bin,dt_data) "
+ "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_data) "
"values");
size = strlen(query);
}
@@ -402,9 +348,9 @@ InsertData::insert()
first = false;
- size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")",
+ size += sprintf(query + size, "(%u,%d,%d,%u,%llu,\"%f\")",
stat, x, y, MySqlDB.run(), (unsigned long long)tick,
- bin, data);
+ data);
}
struct InsertSubData
@@ -656,29 +602,6 @@ MySql::configure(const FormulaData &data)
InsertFormula(find(data.id), data.str());
}
-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);
- }
- }
-}
-
bool
MySql::valid() const
{
@@ -697,11 +620,14 @@ MySql::output()
// store sample #
newdata.tick = curTick;
- output(NULL);
- if (!bins().empty()) {
- bin_list_t::iterator i, end = bins().end();
- for (i = bins().begin(); i != end; ++i)
- output(*i);
+ 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();
diff --git a/src/base/stats/mysql.hh b/src/base/stats/mysql.hh
index 1d88fbcd9..50f7d9e97 100644
--- a/src/base/stats/mysql.hh
+++ b/src/base/stats/mysql.hh
@@ -39,7 +39,6 @@
namespace MySQL { class Connection; }
namespace Stats {
-class MainBin;
class DistDataData;
class MySqlRun;
bool MySqlConnected();
@@ -82,7 +81,6 @@ class InsertData
uint64_t tick;
double data;
uint16_t stat;
- uint16_t bin;
int16_t x;
int16_t y;
@@ -133,7 +131,6 @@ class MySql : public Output
protected:
// Output helper
- void output(MainBin *bin);
void output(const DistDataData &data);
void output(const ScalarData &data);
void output(const VectorData &data);
diff --git a/src/base/stats/statdb.cc b/src/base/stats/statdb.cc
index 682f62dc1..f9136807a 100644
--- a/src/base/stats/statdb.cc
+++ b/src/base/stats/statdb.cc
@@ -31,7 +31,6 @@
#include "base/misc.hh"
#include "base/trace.hh"
#include "base/statistics.hh"
-#include "base/stats/bin.hh"
#include "base/stats/statdb.hh"
using namespace std;
@@ -51,17 +50,6 @@ find(void *stat)
}
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);
-}
-
-void
regStat(void *stat, StatData *data)
{
if (map().find(stat) != map().end())
diff --git a/src/base/stats/statdb.hh b/src/base/stats/statdb.hh
index 8c56e031e..a5b9be7eb 100644
--- a/src/base/stats/statdb.hh
+++ b/src/base/stats/statdb.hh
@@ -40,31 +40,25 @@ class Python;
namespace Stats {
-class MainBin;
class StatData;
namespace Database {
typedef std::map<void *, StatData *> stat_map_t;
typedef std::list<StatData *> stat_list_t;
-typedef std::list<MainBin *> bin_list_t;
// 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;
- bin_list_t bins;
-
};
TheDatabase &db();
inline stat_map_t &map() { return db().map; }
inline stat_list_t &stats() { return db().stats; }
-inline bin_list_t &bins() { return db().bins; }
StatData *find(void *stat);
-void regBin(MainBin *bin, const std::string &name);
void regStat(void *stat, StatData *data);
void regPrint(void *stat);
diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc
index 8d2144665..c4448efc9 100644
--- a/src/base/stats/text.cc
+++ b/src/base/stats/text.cc
@@ -129,23 +129,9 @@ Text::output()
using namespace Database;
ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
- 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");
- }
- }
+ 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();
}
diff --git a/src/base/stats/text.hh b/src/base/stats/text.hh
index de27abe1b..b3faf5ad5 100644
--- a/src/base/stats/text.hh
+++ b/src/base/stats/text.hh
@@ -46,7 +46,6 @@ class Text : public Output
protected:
bool noOutput(const StatData &data);
- void binout();
public:
bool compat;
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index d77f03126..55c04c498 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -89,8 +89,8 @@ BaseCPU::BaseCPU(Params *p)
//
if (p->max_insts_any_thread != 0)
for (int i = 0; i < number_of_threads; ++i)
- new SimExitEvent(comInstEventQueue[i], p->max_insts_any_thread,
- "a thread reached the max instruction count");
+ new SimLoopExitEvent(comInstEventQueue[i], p->max_insts_any_thread,
+ "a thread reached the max instruction count");
if (p->max_insts_all_threads != 0) {
// allocate & initialize shared downcounter: each event will
@@ -114,8 +114,8 @@ BaseCPU::BaseCPU(Params *p)
//
if (p->max_loads_any_thread != 0)
for (int i = 0; i < number_of_threads; ++i)
- new SimExitEvent(comLoadEventQueue[i], p->max_loads_any_thread,
- "a thread reached the max load count");
+ new SimLoopExitEvent(comLoadEventQueue[i], p->max_loads_any_thread,
+ "a thread reached the max load count");
if (p->max_loads_all_threads != 0) {
// allocate & initialize shared downcounter: each event will
diff --git a/src/cpu/o3/alpha_cpu_impl.hh b/src/cpu/o3/alpha_cpu_impl.hh
index fb2fea8e6..bfd05d260 100644
--- a/src/cpu/o3/alpha_cpu_impl.hh
+++ b/src/cpu/o3/alpha_cpu_impl.hh
@@ -46,6 +46,7 @@
#include "arch/isa_traits.hh"
#include "cpu/quiesce_event.hh"
#include "kern/kernel_stats.hh"
+#include "sim/sim_exit.hh"
#include "sim/system.hh"
#endif
@@ -735,7 +736,7 @@ AlphaFullCPU<Impl>::simPalCheck(int palFunc, unsigned tid)
case PAL::halt:
halt();
if (--System::numSystemsRunning == 0)
- new SimExitEvent("all cpus halted");
+ exitSimLoop("all cpus halted");
break;
case PAL::bpt:
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index c1ecf3967..d94b0e079 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -409,11 +409,6 @@ void
BaseSimpleCPU::postExecute()
{
#if FULL_SYSTEM
- if (system->kernelBinning->fnbin) {
- assert(thread->getKernelStats());
- system->kernelBinning->execute(tc, inst);
- }
-
if (thread->profile) {
bool usermode =
(thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index e3bb7d9c3..3c79e1116 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -245,7 +245,6 @@ class ThreadContext
virtual void setSyscallReturn(SyscallReturn return_value) = 0;
-
// Same with st cond failures.
virtual Counter readFuncExeInst() = 0;
#endif
@@ -431,7 +430,6 @@ class ProxyThreadContext : public ThreadContext
void setSyscallReturn(SyscallReturn return_value)
{ actualTC->setSyscallReturn(return_value); }
-
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
#endif
diff --git a/src/cpu/trace/opt_cpu.cc b/src/cpu/trace/opt_cpu.cc
index 098031d4a..996e89f01 100644
--- a/src/cpu/trace/opt_cpu.cc
+++ b/src/cpu/trace/opt_cpu.cc
@@ -176,7 +176,7 @@ OptCPU::tick()
fprintf(stderr,"sys.cpu.misses %d #opt cache misses\n",misses);
fprintf(stderr,"sys.cpu.hits %d #opt cache hits\n", hits);
fprintf(stderr,"sys.cpu.accesses %d #opt cache acceses\n", references);
- new SimExitEvent("Finshed Memory Trace");
+ exitSimLoop("end of memory trace reached");
}
void
diff --git a/src/cpu/trace/trace_cpu.cc b/src/cpu/trace/trace_cpu.cc
index 4df47229f..3c9da4849 100644
--- a/src/cpu/trace/trace_cpu.cc
+++ b/src/cpu/trace/trace_cpu.cc
@@ -108,7 +108,7 @@ TraceCPU::tick()
if (!nextReq) {
// No more requests to send. Finish trailing events and exit.
if (mainEventQueue.empty()) {
- new SimExitEvent("Finshed Memory Trace");
+ exitSimLoop("end of memory trace reached");
} else {
tickEvent.schedule(mainEventQueue.nextEventTime() + cycles(1));
}
diff --git a/src/kern/kernel_stats.cc b/src/kern/kernel_stats.cc
index 2ba120b6f..f7868b50f 100644
--- a/src/kern/kernel_stats.cc
+++ b/src/kern/kernel_stats.cc
@@ -45,13 +45,12 @@ using namespace Stats;
namespace Kernel {
-const char *modestr[] = { "kernel", "user", "idle", "interrupt" };
+const char *modestr[] = { "kernel", "user", "idle" };
Statistics::Statistics(System *system)
: idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
iplLast(0), iplLastTick(0)
{
- bin_int = system->params()->bin_int;
}
void
@@ -186,7 +185,7 @@ Statistics::regStats(const string &_name)
void
Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc)
{
- assert(themode == kernel || themode == interrupt);
+ assert(themode == kernel);
idleProcess = idlepcbb;
themode = idle;
changeMode(themode, tc);
@@ -206,8 +205,6 @@ Statistics::changeMode(cpu_mode newmode, ThreadContext *tc)
_modeGood[newmode]++;
_modeTicks[themode] += curTick - lastModeTick;
- tc->getSystemPtr()->kernelBinning->changeMode(newmode);
-
lastModeTick = curTick;
themode = newmode;
}
@@ -233,13 +230,9 @@ Statistics::mode(cpu_mode newmode, ThreadContext *tc)
{
Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23);
- if ((newmode == kernel || newmode == interrupt) &&
- pcbb == idleProcess)
+ if (newmode == kernel && pcbb == idleProcess)
newmode = idle;
- if (bin_int == false && newmode == interrupt)
- newmode = kernel;
-
changeMode(newmode, tc);
}
@@ -268,11 +261,6 @@ Statistics::callpal(int code, ThreadContext *tc)
_syscall[cvtnum]++;
}
} break;
-
- case PAL::swpctx:
- if (tc->getSystemPtr()->kernelBinning)
- tc->getSystemPtr()->kernelBinning->palSwapContext(tc);
- break;
}
}
diff --git a/src/kern/kernel_stats.hh b/src/kern/kernel_stats.hh
index 781b6f6da..c691ad8cf 100644
--- a/src/kern/kernel_stats.hh
+++ b/src/kern/kernel_stats.hh
@@ -47,95 +47,17 @@ class System;
namespace Kernel {
-enum cpu_mode { kernel, user, idle, interrupt, cpu_mode_num };
+enum cpu_mode { kernel, user, idle, cpu_mode_num };
extern const char *modestr[];
-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);
-};
-
class Statistics : public Serializable
{
private:
- friend class Binning;
-
- private:
std::string myname;
Addr idleProcess;
cpu_mode themode;
Tick lastModeTick;
- bool bin_int;
void changeMode(cpu_mode newmode, ThreadContext *tc);
diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc
index fe3805ce2..177ce96d1 100644
--- a/src/kern/system_events.cc
+++ b/src/kern/system_events.cc
@@ -55,22 +55,6 @@ SkipFuncEvent::process(ThreadContext *tc)
*/
}
-
-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);
-}
-
void
IdleStartEvent::process(ThreadContext *tc)
{
@@ -79,19 +63,3 @@ IdleStartEvent::process(ThreadContext *tc)
tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc);
remove();
}
-
-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);
-}
diff --git a/src/kern/system_events.hh b/src/kern/system_events.hh
index 05c878577..ccd6bd9a4 100644
--- a/src/kern/system_events.hh
+++ b/src/kern/system_events.hh
@@ -45,19 +45,6 @@ class SkipFuncEvent : public PCEvent
virtual void process(ThreadContext *tc);
};
-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;
-};
-
class IdleStartEvent : public PCEvent
{
public:
@@ -67,23 +54,4 @@ class IdleStartEvent : public PCEvent
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);
-};
-
-
#endif // __SYSTEM_EVENTS_HH__
diff --git a/src/python/SConscript b/src/python/SConscript
index 5a787cfdf..7b0f591eb 100644
--- a/src/python/SConscript
+++ b/src/python/SConscript
@@ -38,11 +38,8 @@ def join(*args):
Import('env')
-# This SConscript is in charge of collecting .py files and generating a zip archive that is appended to the m5 binary.
-
-# Copy .py source files here (relative to src/python in the build
-# directory).
-pyzip_root = 'zip'
+# This SConscript is in charge of collecting .py files and generating
+# a zip archive that is appended to the m5 binary.
# List of files & directories to include in the zip file. To include
# a package, list only the root directory of the package, not any
@@ -58,7 +55,7 @@ pyzip_dep_files = []
# Add the specified package to the zip archive. Adds the directory to
# pyzip_files and all included .py files to pyzip_dep_files.
def addPkg(pkgdir):
- pyzip_files.append(join(pyzip_root, pkgdir))
+ pyzip_files.append(pkgdir)
origdir = os.getcwd()
srcdir = join(Dir('.').srcnode().abspath, pkgdir)
os.chdir(srcdir)
@@ -70,10 +67,7 @@ def addPkg(pkgdir):
for f in files:
if f.endswith('.py'):
- source = join(pkgdir, path, f)
- target = join(pyzip_root, source)
- pyzip_dep_files.append(target)
- env.CopyFile(target, source)
+ pyzip_dep_files.append(join(pkgdir, path, f))
os.chdir(origdir)
@@ -81,19 +75,25 @@ def addPkg(pkgdir):
# build_env flags.
def MakeDefinesPyFile(target, source, env):
f = file(str(target[0]), 'w')
- print >>f, "import __main__"
- print >>f, "__main__.m5_build_env = ",
+ print >>f, "m5_build_env = ",
print >>f, source[0]
f.close()
optionDict = dict([(opt, env[opt]) for opt in env.ExportOptions])
-env.Command('defines.py', Value(optionDict), MakeDefinesPyFile)
+env.Command('m5/defines.py', Value(optionDict), MakeDefinesPyFile)
# Now specify the packages & files for the zip archive.
addPkg('m5')
-pyzip_files.append('defines.py')
+pyzip_files.append('m5/defines.py')
pyzip_files.append(join(env['ROOT'], 'util/pbs/jobfile.py'))
+env.Command(['swig/main_wrap.cc', 'm5/main.py'],
+ 'swig/main.i',
+ '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
+ '-o ${TARGETS[0]} $SOURCES')
+
+pyzip_dep_files.append('m5/main.py')
+
# Action function to build the zip archive. Uses the PyZipFile module
# included in the standard Python library.
def buildPyZip(target, source, env):
diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py
index 4f29c55e8..60a61d66e 100644
--- a/src/python/m5/__init__.py
+++ b/src/python/m5/__init__.py
@@ -27,69 +27,26 @@
# Authors: Nathan Binkert
# Steve Reinhardt
-import sys, os, time
+import sys, os, time, atexit, optparse
-import __main__
+# import the SWIG-wrapped main C++ functions
+import main
+# import a few SWIG-wrapped items (those that are likely to be used
+# directly by user scripts) completely into this module for
+# convenience
+from main import simulate, SimLoopExitEvent
-briefCopyright = '''
-Copyright (c) 2001-2006
-The Regents of The University of Michigan
-All Rights Reserved
-'''
-
-fullCopyright = '''
-Copyright (c) 2001-2006
-The Regents of The University of Michigan
-All Rights Reserved
-
-Permission is granted to use, copy, create derivative works and
-redistribute this software and such derivative works for any purpose,
-so long as the copyright notice above, this grant of permission, and
-the disclaimer below appear in all copies made; and so long as the
-name of The University of Michigan is not used in any advertising or
-publicity pertaining to the use or distribution of this software
-without specific, written prior authorization.
-
-THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
-UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT
-WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR
-IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF
-THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES,
-INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION
-WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-'''
-
-def sayHello(f):
- print >> f, "M5 Simulator System"
- print >> f, briefCopyright
- print >> f, "M5 compiled on", __main__.compileDate
- hostname = os.environ.get('HOSTNAME')
- if not hostname:
- hostname = os.environ.get('HOST')
- if hostname:
- print >> f, "M5 executing on", hostname
- print >> f, "M5 simulation started", time.ctime()
-
-sayHello(sys.stderr)
+# import the m5 compile options
+import defines
# define this here so we can use it right away if necessary
def panic(string):
print >>sys.stderr, 'panic:', string
sys.exit(1)
-def m5execfile(f, global_dict):
- # copy current sys.path
- oldpath = sys.path[:]
- # push file's directory onto front of path
- sys.path.insert(0, os.path.abspath(os.path.dirname(f)))
- execfile(f, global_dict)
- # restore original path
- sys.path = oldpath
-
-# Prepend given directory to system module search path.
+# Prepend given directory to system module search path. We may not
+# need this anymore if we can structure our config library more like a
+# Python package.
def AddToPath(path):
# if it's a relative path and we know what directory the current
# python script is in, make the path relative to that directory.
@@ -100,85 +57,58 @@ def AddToPath(path):
# so place the new dir right after that.
sys.path.insert(1, path)
-# find the m5 compile options: must be specified as a dict in
-# __main__.m5_build_env.
-import __main__
-if not hasattr(__main__, 'm5_build_env'):
- panic("__main__ must define m5_build_env")
+
+# Callback to set trace flags. Not necessarily the best way to do
+# things in the long run (particularly if we change how these global
+# options are handled).
+def setTraceFlags(option, opt_str, value, parser):
+ objects.Trace.flags = value
+
+# Standard optparse options. Need to be explicitly included by the
+# user script when it calls optparse.OptionParser().
+standardOptions = [
+ optparse.make_option("--traceflags", type="string", action="callback",
+ callback=setTraceFlags)
+ ]
# make a SmartDict out of the build options for our local use
import smartdict
build_env = smartdict.SmartDict()
-build_env.update(__main__.m5_build_env)
+build_env.update(defines.m5_build_env)
# make a SmartDict out of the OS environment too
env = smartdict.SmartDict()
env.update(os.environ)
-# import the main m5 config code
-from config import *
-
-# import the built-in object definitions
-from objects import *
-
-
-args_left = sys.argv[1:]
-configfile_found = False
-
-while args_left:
- arg = args_left.pop(0)
- if arg.startswith('--'):
- # if arg starts with '--', parse as a special python option
- # of the format --<python var>=<string value>
- try:
- (var, val) = arg.split('=', 1)
- var = var[2:]
- except ValueError:
- panic("Could not parse configuration argument '%s'\n"
- "Expecting --<variable>=<value>\n" % arg);
- exec "%s = %s" % (var, repr(val))
- elif arg.startswith('-'):
- # if the arg starts with '-', it should be a simulator option
- # with a format similar to getopt.
- optchar = arg[1]
- if len(arg) > 2:
- args_left.insert(0, arg[2:])
- if optchar == 'd':
- outdir = args_left.pop(0)
- elif optchar == 'h':
- showBriefHelp(sys.stderr)
- sys.exit(1)
- elif optchar == 'E':
- env_str = args_left.pop(0)
- split_result = env_str.split('=', 1)
- var = split_result[0]
- if len(split_result == 2):
- val = split_result[1]
- else:
- val = True
- env[var] = val
- elif optchar == 'I':
- AddToPath(args_left.pop(0))
- elif optchar == 'P':
- exec args_left.pop(0)
- else:
- showBriefHelp(sys.stderr)
- panic("invalid argument '%s'\n" % arg_str)
- else:
- # In any other case, treat the option as a configuration file
- # name and load it.
- if not arg.endswith('.py'):
- panic("Config file '%s' must end in '.py'\n" % arg)
- configfile_found = True
- m5execfile(arg, globals())
-
-
-if not configfile_found:
- panic("no configuration file specified!")
-
-if globals().has_key('root') and isinstance(root, Root):
+# The final hook to generate .ini files. Called from the user script
+# once the config is built.
+def instantiate(root):
+ config.ticks_per_sec = float(root.clock.frequency)
+ # ugly temporary hack to get output to config.ini
sys.stdout = file('config.ini', 'w')
- instantiate(root)
-else:
- print 'Instantiation skipped: no root object found.'
-
+ root.print_ini()
+ sys.stdout.close() # close config.ini
+ sys.stdout = sys.__stdout__ # restore to original
+ main.initialize() # load config.ini into C++ and process it
+ noDot = True # temporary until we fix dot
+ if not noDot:
+ dot = pydot.Dot()
+ instance.outputDot(dot)
+ dot.orientation = "portrait"
+ dot.size = "8.5,11"
+ dot.ranksep="equally"
+ dot.rank="samerank"
+ dot.write("config.dot")
+ dot.write_ps("config.ps")
+
+# Export curTick to user script.
+def curTick():
+ return main.cvar.curTick
+
+# register our C++ exit callback function with Python
+atexit.register(main.doExitCleanup)
+
+# This import allows user scripts to reference 'm5.objects.Foo' after
+# just doing an 'import m5' (without an 'import m5.objects'). May not
+# matter since most scripts will probably 'from m5.objects import *'.
+import objects
diff --git a/src/python/m5/config.py b/src/python/m5/config.py
index d1471c807..97e13c900 100644
--- a/src/python/m5/config.py
+++ b/src/python/m5/config.py
@@ -27,11 +27,10 @@
# Authors: Steve Reinhardt
# Nathan Binkert
-from __future__ import generators
import os, re, sys, types, inspect
import m5
-panic = m5.panic
+from m5 import panic
from convert import *
from multidict import multidict
@@ -137,8 +136,15 @@ class Singleton(type):
def isSimObject(value):
return isinstance(value, SimObject)
-def isSimObjSequence(value):
- if not isinstance(value, (list, tuple)):
+def isSimObjectClass(value):
+ try:
+ return issubclass(value, SimObject)
+ except TypeError:
+ # happens if value is not a class at all
+ return False
+
+def isSimObjectSequence(value):
+ if not isinstance(value, (list, tuple)) or len(value) == 0:
return False
for val in value:
@@ -147,9 +153,41 @@ def isSimObjSequence(value):
return True
+def isSimObjectClassSequence(value):
+ if not isinstance(value, (list, tuple)) or len(value) == 0:
+ return False
+
+ for val in value:
+ if not isNullPointer(val) and not isSimObjectClass(val):
+ return False
+
+ return True
+
+def isSimObjectOrSequence(value):
+ return isSimObject(value) or isSimObjectSequence(value)
+
+def isSimObjectClassOrSequence(value):
+ return isSimObjectClass(value) or isSimObjectClassSequence(value)
+
def isNullPointer(value):
return isinstance(value, NullSimObject)
+# Apply method to object.
+# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
+def applyMethod(obj, meth, *args, **kwargs):
+ return getattr(obj, meth)(*args, **kwargs)
+
+# If the first argument is an (non-sequence) object, apply the named
+# method with the given arguments. If the first argument is a
+# sequence, apply the method to each element of the sequence (a la
+# 'map').
+def applyOrMap(objOrSeq, meth, *args, **kwargs):
+ if not isinstance(objOrSeq, (list, tuple)):
+ return applyMethod(objOrSeq, meth, *args, **kwargs)
+ else:
+ return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq]
+
+
# The metaclass for ConfigNode (and thus for everything that derives
# from ConfigNode, including SimObject). This class controls how new
# classes that derive from ConfigNode are instantiated, and provides
@@ -170,24 +208,32 @@ class MetaSimObject(type):
# and only allow "private" attributes to be passed to the base
# __new__ (starting with underscore).
def __new__(mcls, name, bases, dict):
- # Copy "private" attributes (including special methods such as __new__)
- # to the official dict. Everything else goes in _init_dict to be
- # filtered in __init__.
- cls_dict = {}
- for key,val in dict.items():
- if key.startswith('_'):
- cls_dict[key] = val
- del dict[key]
- cls_dict['_init_dict'] = dict
+ if dict.has_key('_init_dict'):
+ # must have been called from makeSubclass() rather than
+ # via Python class declaration; bypass filtering process.
+ cls_dict = dict
+ else:
+ # Copy "private" attributes (including special methods
+ # such as __new__) to the official dict. Everything else
+ # goes in _init_dict to be filtered in __init__.
+ cls_dict = {}
+ for key,val in dict.items():
+ if key.startswith('_'):
+ cls_dict[key] = val
+ del dict[key]
+ cls_dict['_init_dict'] = dict
return super(MetaSimObject, mcls).__new__(mcls, name, bases, cls_dict)
- # initialization
+ # subclass initialization
def __init__(cls, name, bases, dict):
+ # calls type.__init__()... I think that's a no-op, but leave
+ # it here just in case it's not.
super(MetaSimObject, cls).__init__(name, bases, dict)
# initialize required attributes
cls._params = multidict()
cls._values = multidict()
+ cls._instantiated = False # really instantiated or subclassed
cls._anon_subclass_counter = 0
# We don't support multiple inheritance. If you want to, you
@@ -197,27 +243,14 @@ class MetaSimObject(type):
base = bases[0]
+ # the only time the following is not true is when we define
+ # the SimObject class itself
if isinstance(base, MetaSimObject):
cls._params.parent = base._params
cls._values.parent = base._values
+ base._instantiated = True
- # If your parent has a value in it that's a config node, clone
- # it. Do this now so if we update any of the values'
- # attributes we are updating the clone and not the original.
- for key,val in base._values.iteritems():
-
- # don't clone if (1) we're about to overwrite it with
- # a local setting or (2) we've already cloned a copy
- # from an earlier (more derived) base
- if cls._init_dict.has_key(key) or cls._values.has_key(key):
- continue
-
- if isSimObject(val):
- cls._values[key] = val()
- elif isSimObjSequence(val) and len(val):
- cls._values[key] = [ v() for v in val ]
-
- # now process remaining _init_dict items
+ # now process the _init_dict items
for key,val in cls._init_dict.items():
if isinstance(val, (types.FunctionType, types.TypeType)):
type.__setattr__(cls, key, val)
@@ -234,6 +267,27 @@ class MetaSimObject(type):
else:
setattr(cls, key, val)
+ # Pull the deep-copy memoization dict out of the class dict if
+ # it's there...
+ memo = cls.__dict__.get('_memo', {})
+
+ # Handle SimObject values
+ for key,val in cls._values.iteritems():
+ # SimObject instances need to be promoted to classes.
+ # Existing classes should not have any instance values, so
+ # these can only occur at the lowest level dict (the
+ # parameters just being set in this class definition).
+ if isSimObjectOrSequence(val):
+ assert(val == cls._values.local[key])
+ cls._values[key] = applyOrMap(val, 'makeClass', memo)
+ # SimObject classes need to be subclassed so that
+ # parameters that get set at this level only affect this
+ # level and derivatives.
+ elif isSimObjectClassOrSequence(val):
+ assert(not cls._values.local.has_key(key))
+ cls._values[key] = applyOrMap(val, 'makeSubclass', {}, memo)
+
+
def _set_keyword(cls, keyword, val, kwtype):
if not isinstance(val, kwtype):
raise TypeError, 'keyword %s has bad type %s (expecting %s)' % \
@@ -263,6 +317,11 @@ class MetaSimObject(type):
param = cls._params.get(attr, None)
if param:
# It's ok: set attribute by delegating to 'object' class.
+ if isSimObjectOrSequence(value) and cls._instantiated:
+ raise AttributeError, \
+ "Cannot set SimObject parameter '%s' after\n" \
+ " class %s has been instantiated or subclassed" \
+ % (attr, cls.__name__)
try:
cls._values[attr] = param.convert(value)
except Exception, e:
@@ -271,7 +330,7 @@ class MetaSimObject(type):
e.args = (msg, )
raise
# I would love to get rid of this
- elif isSimObject(value) or isSimObjSequence(value):
+ elif isSimObjectOrSequence(value):
cls._values[attr] = value
else:
raise AttributeError, \
@@ -284,6 +343,22 @@ class MetaSimObject(type):
raise AttributeError, \
"object '%s' has no attribute '%s'" % (cls.__name__, attr)
+ # Create a subclass of this class. Basically a function interface
+ # to the standard Python class definition mechanism, primarily for
+ # internal use. 'memo' dict param supports "deep copy" (really
+ # "deep subclass") operations... within a given operation,
+ # multiple references to a class should result in a single
+ # subclass object with multiple references to it (as opposed to
+ # mutiple unique subclasses).
+ def makeSubclass(cls, init_dict, memo = {}):
+ subcls = memo.get(cls)
+ if not subcls:
+ name = cls.__name__ + '_' + str(cls._anon_subclass_counter)
+ cls._anon_subclass_counter += 1
+ subcls = MetaSimObject(name, (cls,),
+ { '_init_dict': init_dict, '_memo': memo })
+ return subcls
+
# The ConfigNode class is the root of the special hierarchy. Most of
# the code in this class deals with the configuration hierarchy itself
# (parent/child node relationships).
@@ -292,27 +367,80 @@ class SimObject(object):
# get this metaclass.
__metaclass__ = MetaSimObject
- def __init__(self, _value_parent = None, **kwargs):
+ # __new__ operator allocates new instances of the class. We
+ # override it here just to support "deep instantiation" operation
+ # via the _memo dict. When recursively instantiating an object
+ # hierarchy we want to make sure that each class is instantiated
+ # only once, and that if there are multiple references to the same
+ # original class, we end up with the corresponding instantiated
+ # references all pointing to the same instance.
+ def __new__(cls, _memo = None, **kwargs):
+ if _memo is not None and _memo.has_key(cls):
+ # return previously instantiated object
+ assert(len(kwargs) == 0)
+ return _memo[cls]
+ else:
+ # Need a new one... if it needs to be memoized, this will
+ # happen in __init__. We defer the insertion until then
+ # so __init__ can use the memo dict to tell whether or not
+ # to perform the initialization.
+ return super(SimObject, cls).__new__(cls, **kwargs)
+
+ # Initialize new instance previously allocated by __new__. For
+ # objects with SimObject-valued params, we need to recursively
+ # instantiate the classes represented by those param values as
+ # well (in a consistent "deep copy"-style fashion; see comment
+ # above).
+ def __init__(self, _memo = None, **kwargs):
+ if _memo is not None:
+ # We're inside a "deep instantiation"
+ assert(isinstance(_memo, dict))
+ assert(len(kwargs) == 0)
+ if _memo.has_key(self.__class__):
+ # __new__ returned an existing, already initialized
+ # instance, so there's nothing to do here
+ assert(_memo[self.__class__] == self)
+ return
+ # no pre-existing object, so remember this one here
+ _memo[self.__class__] = self
+ else:
+ # This is a new top-level instantiation... don't memoize
+ # this objcet, but prepare to memoize any recursively
+ # instantiated objects.
+ _memo = {}
+
+ self.__class__._instantiated = True
+
self._children = {}
- if _value_parent and type(_value_parent) != type(self):
- # this was called as a type conversion rather than a clone
- raise TypeError, "Cannot convert %s to %s" % \
- (_value_parent.__class__.__name__, self.__class__.__name__)
- if not _value_parent:
- _value_parent = self.__class__
- # clone values
- self._values = multidict(_value_parent._values)
- for key,val in _value_parent._values.iteritems():
- if isSimObject(val):
- setattr(self, key, val())
- elif isSimObjSequence(val) and len(val):
- setattr(self, key, [ v() for v in val ])
+ # Inherit parameter values from class using multidict so
+ # individual value settings can be overridden.
+ self._values = multidict(self.__class__._values)
+ # For SimObject-valued parameters, the class should have
+ # classes (not instances) for the values. We need to
+ # instantiate these classes rather than just inheriting the
+ # class object.
+ for key,val in self.__class__._values.iteritems():
+ if isSimObjectClass(val):
+ setattr(self, key, val(_memo))
+ elif isSimObjectClassSequence(val) and len(val):
+ setattr(self, key, [ v(_memo) for v in val ])
# apply attribute assignments from keyword args, if any
for key,val in kwargs.iteritems():
setattr(self, key, val)
+ # Use this instance as a template to create a new class.
+ def makeClass(self, memo = {}):
+ cls = memo.get(self)
+ if not cls:
+ cls = self.__class__.makeSubclass(self._values.local)
+ memo[self] = cls
+ return cls
+
+ # Direct instantiation of instances (cloning) is no longer
+ # allowed; must generate class from instance first.
def __call__(self, **kwargs):
- return self.__class__(_value_parent = self, **kwargs)
+ raise TypeError, "cannot instantiate SimObject; "\
+ "use makeClass() to make class first"
def __getattr__(self, attr):
if self._values.has_key(attr):
@@ -341,7 +469,7 @@ class SimObject(object):
e.args = (msg, )
raise
# I would love to get rid of this
- elif isSimObject(value) or isSimObjSequence(value):
+ elif isSimObjectOrSequence(value):
pass
else:
raise AttributeError, "Class %s has no parameter %s" \
@@ -352,7 +480,7 @@ class SimObject(object):
if isSimObject(value):
value.set_path(self, attr)
- elif isSimObjSequence(value):
+ elif isSimObjectSequence(value):
value = SimObjVector(value)
[v.set_path(self, "%s%d" % (attr, i)) for i,v in enumerate(value)]
@@ -728,7 +856,7 @@ class ParamDesc(object):
def __getattr__(self, attr):
if attr == 'ptype':
try:
- ptype = eval(self.ptype_str, m5.__dict__)
+ ptype = eval(self.ptype_str, m5.objects.__dict__)
if not isinstance(ptype, type):
panic("Param qualifier is not a type: %s" % self.ptype)
self.ptype = ptype
@@ -775,7 +903,7 @@ class VectorParamDesc(ParamDesc):
if isinstance(value, (list, tuple)):
# list: coerce each element into new list
tmp_list = [ ParamDesc.convert(self, v) for v in value ]
- if isSimObjSequence(tmp_list):
+ if isSimObjectSequence(tmp_list):
return SimObjVector(tmp_list)
else:
return VectorParamValue(tmp_list)
@@ -1069,7 +1197,10 @@ class EthernetAddr(ParamValue):
def __str__(self):
if self.value == NextEthernetAddr:
- return self.addr
+ if hasattr(self, 'addr'):
+ return self.addr
+ else:
+ return "NextEthernetAddr (unresolved)"
else:
return self.value
@@ -1290,23 +1421,6 @@ AllMemory = AddrRange(0, MaxAddr)
#####################################################################
-# The final hook to generate .ini files. Called from configuration
-# script once config is built.
-def instantiate(root):
- global ticks_per_sec
- ticks_per_sec = float(root.clock.frequency)
- root.print_ini()
- noDot = True # temporary until we fix dot
- if not noDot:
- dot = pydot.Dot()
- instance.outputDot(dot)
- dot.orientation = "portrait"
- dot.size = "8.5,11"
- dot.ranksep="equally"
- dot.rank="samerank"
- dot.write("config.dot")
- dot.write_ps("config.ps")
-
# __all__ defines the list of symbols that get exported when
# 'from config import *' is invoked. Try to keep this reasonably
# short to avoid polluting other namespaces.
@@ -1322,5 +1436,5 @@ __all__ = ['SimObject', 'ParamContext', 'Param', 'VectorParam',
'NetworkBandwidth', 'MemoryBandwidth',
'Range', 'AddrRange', 'MaxAddr', 'MaxTick', 'AllMemory',
'Null', 'NULL',
- 'NextEthernetAddr', 'instantiate']
+ 'NextEthernetAddr']
diff --git a/src/python/m5/multidict.py b/src/python/m5/multidict.py
index 698e85b26..34fc3139b 100644
--- a/src/python/m5/multidict.py
+++ b/src/python/m5/multidict.py
@@ -31,7 +31,7 @@ __all__ = [ 'multidict' ]
class multidict(object):
__nodefault = object()
def __init__(self, parent = {}, **kwargs):
- self.dict = dict(**kwargs)
+ self.local = dict(**kwargs)
self.parent = parent
self.deleted = {}
@@ -42,11 +42,11 @@ class multidict(object):
return `dict(self.items())`
def __contains__(self, key):
- return self.dict.has_key(key) or self.parent.has_key(key)
+ return self.local.has_key(key) or self.parent.has_key(key)
def __delitem__(self, key):
try:
- del self.dict[key]
+ del self.local[key]
except KeyError, e:
if key in self.parent:
self.deleted[key] = True
@@ -55,11 +55,11 @@ class multidict(object):
def __setitem__(self, key, value):
self.deleted.pop(key, False)
- self.dict[key] = value
+ self.local[key] = value
def __getitem__(self, key):
try:
- return self.dict[key]
+ return self.local[key]
except KeyError, e:
if not self.deleted.get(key, False) and key in self.parent:
return self.parent[key]
@@ -67,15 +67,15 @@ class multidict(object):
raise KeyError, e
def __len__(self):
- return len(self.dict) + len(self.parent)
+ return len(self.local) + len(self.parent)
def next(self):
- for key,value in self.dict.items():
+ for key,value in self.local.items():
yield key,value
if self.parent:
for key,value in self.parent.next():
- if key not in self.dict and key not in self.deleted:
+ if key not in self.local and key not in self.deleted:
yield key,value
def has_key(self, key):
@@ -116,22 +116,22 @@ class multidict(object):
return self[key]
except KeyError:
self.deleted.pop(key, False)
- self.dict[key] = default
+ self.local[key] = default
return default
def _dump(self):
print 'multidict dump'
node = self
while isinstance(node, multidict):
- print ' ', node.dict
+ print ' ', node.local
node = node.parent
def _dumpkey(self, key):
values = []
node = self
while isinstance(node, multidict):
- if key in node.dict:
- values.append(node.dict[key])
+ if key in node.local:
+ values.append(node.local[key])
node = node.parent
print key, values
diff --git a/src/python/m5/objects/AlphaConsole.py b/src/python/m5/objects/AlphaConsole.py
index 68e6089ab..329b8c5bd 100644
--- a/src/python/m5/objects/AlphaConsole.py
+++ b/src/python/m5/objects/AlphaConsole.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from Device import BasicPioDevice
class AlphaConsole(BasicPioDevice):
diff --git a/src/python/m5/objects/AlphaFullCPU.py b/src/python/m5/objects/AlphaFullCPU.py
index 7c772d3f2..2988305d3 100644
--- a/src/python/m5/objects/AlphaFullCPU.py
+++ b/src/python/m5/objects/AlphaFullCPU.py
@@ -1,4 +1,5 @@
-from m5 import *
+from m5 import build_env
+from m5.config import *
from BaseCPU import BaseCPU
class DerivAlphaFullCPU(BaseCPU):
diff --git a/src/python/m5/objects/AlphaTLB.py b/src/python/m5/objects/AlphaTLB.py
index 5edf8e13d..11c1792ee 100644
--- a/src/python/m5/objects/AlphaTLB.py
+++ b/src/python/m5/objects/AlphaTLB.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class AlphaTLB(SimObject):
type = 'AlphaTLB'
abstract = True
diff --git a/src/python/m5/objects/BadDevice.py b/src/python/m5/objects/BadDevice.py
index 9cb9a8f03..186b733fa 100644
--- a/src/python/m5/objects/BadDevice.py
+++ b/src/python/m5/objects/BadDevice.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from Device import BasicPioDevice
class BadDevice(BasicPioDevice):
diff --git a/src/python/m5/objects/BaseCPU.py b/src/python/m5/objects/BaseCPU.py
index 49cb2a8f3..2e78578df 100644
--- a/src/python/m5/objects/BaseCPU.py
+++ b/src/python/m5/objects/BaseCPU.py
@@ -1,4 +1,6 @@
-from m5 import *
+from m5 import build_env
+from m5.config import *
+
class BaseCPU(SimObject):
type = 'BaseCPU'
abstract = True
diff --git a/src/python/m5/objects/BaseCache.py b/src/python/m5/objects/BaseCache.py
index 79d21572a..33f44759b 100644
--- a/src/python/m5/objects/BaseCache.py
+++ b/src/python/m5/objects/BaseCache.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from BaseMem import BaseMem
class Prefetch(Enum): vals = ['none', 'tagged', 'stride', 'ghb']
diff --git a/src/python/m5/objects/Bridge.py b/src/python/m5/objects/Bridge.py
index ada715ce9..880535755 100644
--- a/src/python/m5/objects/Bridge.py
+++ b/src/python/m5/objects/Bridge.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from MemObject import MemObject
class Bridge(MemObject):
diff --git a/src/python/m5/objects/Bus.py b/src/python/m5/objects/Bus.py
index 8c5397281..c37dab438 100644
--- a/src/python/m5/objects/Bus.py
+++ b/src/python/m5/objects/Bus.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from MemObject import MemObject
class Bus(MemObject):
diff --git a/src/python/m5/objects/CoherenceProtocol.py b/src/python/m5/objects/CoherenceProtocol.py
index 7013000d6..64b6cbacf 100644
--- a/src/python/m5/objects/CoherenceProtocol.py
+++ b/src/python/m5/objects/CoherenceProtocol.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class Coherence(Enum): vals = ['uni', 'msi', 'mesi', 'mosi', 'moesi']
class CoherenceProtocol(SimObject):
diff --git a/src/python/m5/objects/Device.py b/src/python/m5/objects/Device.py
index 2a71bbc65..7798f5f04 100644
--- a/src/python/m5/objects/Device.py
+++ b/src/python/m5/objects/Device.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from MemObject import MemObject
class PioDevice(MemObject):
diff --git a/src/python/m5/objects/DiskImage.py b/src/python/m5/objects/DiskImage.py
index 0d55e9329..70d8b2e45 100644
--- a/src/python/m5/objects/DiskImage.py
+++ b/src/python/m5/objects/DiskImage.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class DiskImage(SimObject):
type = 'DiskImage'
abstract = True
diff --git a/src/python/m5/objects/Ethernet.py b/src/python/m5/objects/Ethernet.py
index 4286c71c8..418670592 100644
--- a/src/python/m5/objects/Ethernet.py
+++ b/src/python/m5/objects/Ethernet.py
@@ -1,4 +1,5 @@
-from m5 import *
+from m5 import build_env
+from m5.config import *
from Device import DmaDevice
from Pci import PciDevice
diff --git a/src/python/m5/objects/FUPool.py b/src/python/m5/objects/FUPool.py
index 5eecfd12f..cbf1089cf 100644
--- a/src/python/m5/objects/FUPool.py
+++ b/src/python/m5/objects/FUPool.py
@@ -1,7 +1,4 @@
-from m5 import *
-from FullCPU import OpType
-from FullCPU import OpDesc
-from FullCPU import FUDesc
+from m5.config import *
class FUPool(SimObject):
type = 'FUPool'
diff --git a/src/python/m5/objects/Ide.py b/src/python/m5/objects/Ide.py
index 2403e6d36..9ee578177 100644
--- a/src/python/m5/objects/Ide.py
+++ b/src/python/m5/objects/Ide.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from Pci import PciDevice
class IdeID(Enum): vals = ['master', 'slave']
diff --git a/src/python/m5/objects/IntrControl.py b/src/python/m5/objects/IntrControl.py
index 66c82c182..514c3fc62 100644
--- a/src/python/m5/objects/IntrControl.py
+++ b/src/python/m5/objects/IntrControl.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class IntrControl(SimObject):
type = 'IntrControl'
cpu = Param.BaseCPU(Parent.any, "the cpu")
diff --git a/src/python/m5/objects/MemObject.py b/src/python/m5/objects/MemObject.py
index 4d68243e6..d957dae17 100644
--- a/src/python/m5/objects/MemObject.py
+++ b/src/python/m5/objects/MemObject.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class MemObject(SimObject):
type = 'MemObject'
diff --git a/src/python/m5/objects/MemTest.py b/src/python/m5/objects/MemTest.py
index 34299faf0..9916d7cb4 100644
--- a/src/python/m5/objects/MemTest.py
+++ b/src/python/m5/objects/MemTest.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class MemTest(SimObject):
type = 'MemTest'
cache = Param.BaseCache("L1 cache")
diff --git a/src/python/m5/objects/OzoneCPU.py b/src/python/m5/objects/OzoneCPU.py
index ea8b6b537..f2d9aea84 100644
--- a/src/python/m5/objects/OzoneCPU.py
+++ b/src/python/m5/objects/OzoneCPU.py
@@ -1,4 +1,5 @@
-from m5 import *
+from m5 import build_env
+from m5.config import *
from BaseCPU import BaseCPU
class DerivOzoneCPU(BaseCPU):
diff --git a/src/python/m5/objects/Pci.py b/src/python/m5/objects/Pci.py
index 85cefcd44..9e1e91b13 100644
--- a/src/python/m5/objects/Pci.py
+++ b/src/python/m5/objects/Pci.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from Device import BasicPioDevice, DmaDevice
class PciConfigData(SimObject):
diff --git a/src/python/m5/objects/PhysicalMemory.py b/src/python/m5/objects/PhysicalMemory.py
index c59910093..bed90d555 100644
--- a/src/python/m5/objects/PhysicalMemory.py
+++ b/src/python/m5/objects/PhysicalMemory.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from MemObject import *
class PhysicalMemory(MemObject):
diff --git a/src/python/m5/objects/Platform.py b/src/python/m5/objects/Platform.py
index 4da0ffab4..89fee9991 100644
--- a/src/python/m5/objects/Platform.py
+++ b/src/python/m5/objects/Platform.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class Platform(SimObject):
type = 'Platform'
abstract = True
diff --git a/src/python/m5/objects/Process.py b/src/python/m5/objects/Process.py
index 60b00229e..0091d8654 100644
--- a/src/python/m5/objects/Process.py
+++ b/src/python/m5/objects/Process.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class Process(SimObject):
type = 'Process'
abstract = True
diff --git a/src/python/m5/objects/Repl.py b/src/python/m5/objects/Repl.py
index afd256082..8e9f1094f 100644
--- a/src/python/m5/objects/Repl.py
+++ b/src/python/m5/objects/Repl.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class Repl(SimObject):
type = 'Repl'
abstract = True
diff --git a/src/python/m5/objects/Root.py b/src/python/m5/objects/Root.py
index 205a93c76..373475a7a 100644
--- a/src/python/m5/objects/Root.py
+++ b/src/python/m5/objects/Root.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from Serialize import Serialize
from Statistics import Statistics
from Trace import Trace
diff --git a/src/python/m5/objects/SimConsole.py b/src/python/m5/objects/SimConsole.py
index df3061908..9e1452c6d 100644
--- a/src/python/m5/objects/SimConsole.py
+++ b/src/python/m5/objects/SimConsole.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class ConsoleListener(SimObject):
type = 'ConsoleListener'
port = Param.TcpPort(3456, "listen port")
diff --git a/src/python/m5/objects/SimpleDisk.py b/src/python/m5/objects/SimpleDisk.py
index e34155ace..44ef709af 100644
--- a/src/python/m5/objects/SimpleDisk.py
+++ b/src/python/m5/objects/SimpleDisk.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
class SimpleDisk(SimObject):
type = 'SimpleDisk'
disk = Param.DiskImage("Disk Image")
diff --git a/src/python/m5/objects/SimpleOzoneCPU.py b/src/python/m5/objects/SimpleOzoneCPU.py
index 0d6403383..5d968cab0 100644
--- a/src/python/m5/objects/SimpleOzoneCPU.py
+++ b/src/python/m5/objects/SimpleOzoneCPU.py
@@ -1,4 +1,5 @@
-from m5 import *
+from m5 import build_env
+from m5.config import *
from BaseCPU import BaseCPU
class SimpleOzoneCPU(BaseCPU):
diff --git a/src/python/m5/objects/System.py b/src/python/m5/objects/System.py
index 622b5a870..9a1e1d690 100644
--- a/src/python/m5/objects/System.py
+++ b/src/python/m5/objects/System.py
@@ -1,4 +1,5 @@
-from m5 import *
+from m5 import build_env
+from m5.config import *
class System(SimObject):
type = 'System'
@@ -7,8 +8,6 @@ class System(SimObject):
boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency,
"boot processor frequency")
init_param = Param.UInt64(0, "numerical value to pass into simulator")
- bin = Param.Bool(False, "is this system binned")
- binned_fns = VectorParam.String([], "functions broken down and binned")
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")
diff --git a/src/python/m5/objects/Tsunami.py b/src/python/m5/objects/Tsunami.py
index 27ea0bce8..4613571d8 100644
--- a/src/python/m5/objects/Tsunami.py
+++ b/src/python/m5/objects/Tsunami.py
@@ -1,4 +1,4 @@
-from m5 import *
+from m5.config import *
from Device import BasicPioDevice
from Platform import Platform
diff --git a/src/python/m5/objects/Uart.py b/src/python/m5/objects/Uart.py
index 54754aeb9..8e1fd1a37 100644
--- a/src/python/m5/objects/Uart.py
+++ b/src/python/m5/objects/Uart.py
@@ -1,4 +1,5 @@
-from m5 import *
+from m5 import build_env
+from m5.config import *
from Device import BasicPioDevice
class Uart(BasicPioDevice):
diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc
index d90d0923a..6ae838897 100644
--- a/src/sim/eventq.cc
+++ b/src/sim/eventq.cc
@@ -102,7 +102,7 @@ EventQueue::remove(Event *event)
prev->next = curr->next;
}
-void
+Event *
EventQueue::serviceOne()
{
Event *event = head;
@@ -110,13 +110,20 @@ EventQueue::serviceOne()
head = event->next;
// handle action
- if (!event->squashed())
+ if (!event->squashed()) {
event->process();
- else
+ if (event->isExitEvent()) {
+ assert(!event->getFlags(Event::AutoDelete)); // would be silly
+ return event;
+ }
+ } else {
event->clearFlags(Event::Squashed);
+ }
if (event->getFlags(Event::AutoDelete) && !event->scheduled())
delete event;
+
+ return NULL;
}
diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh
index a5cc0c1b6..430473df3 100644
--- a/src/sim/eventq.hh
+++ b/src/sim/eventq.hh
@@ -90,7 +90,8 @@ class Event : public Serializable, public FastAlloc
Squashed = 0x1,
Scheduled = 0x2,
AutoDelete = 0x4,
- AutoSerialize = 0x8
+ AutoSerialize = 0x8,
+ IsExitEvent = 0x10
};
bool getFlags(Flags f) const { return (_flags & f) == f; }
@@ -214,6 +215,9 @@ class Event : public Serializable, public FastAlloc
/// Check whether the event is squashed
bool squashed() { return getFlags(Squashed); }
+ /// See if this is a SimExitEvent (without resorting to RTTI)
+ bool isExitEvent() { return getFlags(IsExitEvent); }
+
/// Get the time that the event is scheduled
Tick when() const { return _when; }
@@ -298,7 +302,7 @@ class EventQueue : public Serializable
void reschedule(Event *ev);
Tick nextTick() { return head->when(); }
- void serviceOne();
+ Event *serviceOne();
// process all events up to the given timestamp. we inline a
// quick test to see if there are any events to process; if so,
diff --git a/src/sim/host.hh b/src/sim/host.hh
index 84870714a..9c79580b1 100644
--- a/src/sim/host.hh
+++ b/src/sim/host.hh
@@ -56,6 +56,8 @@ typedef int64_t Counter;
*/
typedef int64_t Tick;
+const Tick MaxTick = (1LL << 62);
+
/**
* Address type
* This will probably be moved somewhere else in the near future.
diff --git a/src/sim/main.cc b/src/sim/main.cc
index 7728e258a..741926056 100644
--- a/src/sim/main.cc
+++ b/src/sim/main.cc
@@ -41,11 +41,13 @@
#include <libgen.h>
#include <stdlib.h>
#include <signal.h>
+#include <unistd.h>
#include <list>
#include <string>
#include <vector>
+#include "base/callback.hh"
#include "base/inifile.hh"
#include "base/misc.hh"
#include "base/output.hh"
@@ -111,50 +113,39 @@ abortHandler(int sigtype)
#endif
}
-/// Simulator executable name
-char *myProgName = "";
-///
-/// Echo the command line for posterity in such a way that it can be
-/// used to rerun the same simulation (given the same .ini files).
-///
+const char *briefCopyright =
+"Copyright (c) 2001-2006\n"
+"The Regents of The University of Michigan\n"
+"All Rights Reserved\n";
+
+/// Print welcome message.
void
-echoCommandLine(int argc, char **argv, ostream &out)
+sayHello(ostream &out)
{
- out << "command line: " << argv[0];
- for (int i = 1; i < argc; i++) {
- string arg(argv[i]);
+ extern const char *compileDate; // from date.cc
- out << ' ';
+ ccprintf(out, "M5 Simulator System\n");
+ // display copyright
+ ccprintf(out, "%s\n", briefCopyright);
+ ccprintf(out, "M5 compiled %d\n", compileDate);
+ ccprintf(out, "M5 started %s\n", Time::start);
- // If the arg contains spaces, we need to quote it.
- // The rest of this is overkill to make it look purty.
+ char *host = getenv("HOSTNAME");
+ if (!host)
+ host = getenv("HOST");
- // print dashes first outside quotes
- int non_dash_pos = arg.find_first_not_of("-");
- out << arg.substr(0, non_dash_pos); // print dashes
- string body = arg.substr(non_dash_pos); // the rest
+ if (host)
+ ccprintf(out, "M5 executing on %s\n", host);
+}
- // if it's an assignment, handle the lhs & rhs separately
- int eq_pos = body.find("=");
- if (eq_pos == string::npos) {
- out << quote(body);
- }
- else {
- string lhs(body.substr(0, eq_pos));
- string rhs(body.substr(eq_pos + 1));
- out << quote(lhs) << "=" << quote(rhs);
- }
- }
- out << endl << endl;
-}
+extern "C" { void init_main(); }
int
main(int argc, char **argv)
{
- // Save off program name
- myProgName = argv[0];
+ sayHello(cerr);
signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths
signal(SIGTRAP, SIG_IGN);
@@ -163,37 +154,108 @@ main(int argc, char **argv)
signal(SIGINT, exitNowHandler); // dump final stats and exit
signal(SIGABRT, abortHandler);
- // Python embedded interpreter invocation
Py_SetProgramName(argv[0]);
- const char *fileName = Py_GetProgramFullPath();
+
+ // default path to m5 python code is the currently executing
+ // file... Python ZipImporter will find embedded zip archive
+ char *pythonpath = argv[0];
+
+ bool interactive = false;
+ bool getopt_done = false;
+ do {
+ switch (getopt(argc, argv, "+p:i")) {
+ // -p <path> prepends <path> to PYTHONPATH instead of
+ // using built-in zip archive. Useful when
+ // developing/debugging changes to built-in Python
+ // libraries, as the new Python can be tested without
+ // building a new m5 binary.
+ case 'p':
+ pythonpath = optarg;
+ break;
+
+ // -i forces entry into interactive mode after the
+ // supplied script is executed (just like the -i option to
+ // the Python interpreter).
+ case 'i':
+ interactive = true;
+ break;
+
+ case -1:
+ getopt_done = true;
+ break;
+
+ default:
+ fatal("Unrecognized option %c\n", optopt);
+ }
+ } while (!getopt_done);
+
+ // Fix up argc & argv to hide arguments we just processed.
+ // getopt() sets optind to the index of the first non-processed
+ // argv element.
+ argc -= optind;
+ argv += optind;
+
+ // Set up PYTHONPATH to make sure the m5 module is found
+ string newpath(pythonpath);
+
+ char *oldpath = getenv("PYTHONPATH");
+ if (oldpath != NULL) {
+ newpath += ":";
+ newpath += oldpath;
+ }
+
+ if (setenv("PYTHONPATH", newpath.c_str(), true) == -1)
+ fatal("setenv: %s\n", strerror(errno));
+
+ // initialize embedded Python interpreter
Py_Initialize();
PySys_SetArgv(argc, argv);
- // loadSwigModules();
-
- // Set Python module path to include current file to find embedded
- // zip archive
- if (PyRun_SimpleString("import sys") != 0)
- panic("Python error importing 'sys' module\n");
- string pathCmd = csprintf("sys.path[1:1] = ['%s']", fileName);
- if (PyRun_SimpleString(pathCmd.c_str()) != 0)
- panic("Python error setting sys.path\n");
-
- // Pass compile timestamp string to Python
- extern const char *compileDate; // from date.cc
- string setCompileDate = csprintf("compileDate = '%s'", compileDate);
- if (PyRun_SimpleString(setCompileDate.c_str()) != 0)
- panic("Python error setting compileDate\n");
-
- // PyRun_InteractiveLoop(stdin, "stdin");
- // m5/__init__.py currently contains main argv parsing loop etc.,
- // and will write out config.ini file before returning.
- if (PyImport_ImportModule("defines") == NULL)
- panic("Python error importing 'defines.py'\n");
- if (PyImport_ImportModule("m5") == NULL)
- panic("Python error importing 'm5' module\n");
+ // initialize SWIG 'main' module
+ init_main();
+
+ if (argc > 0) {
+ // extra arg(s): first is script file, remaining ones are args
+ // to script file
+ char *filename = argv[0];
+ FILE *fp = fopen(filename, "r");
+ if (!fp) {
+ fatal("cannot open file '%s'\n", filename);
+ }
+
+ PyRun_AnyFile(fp, filename);
+ } else {
+ // no script file argument... force interactive prompt
+ interactive = true;
+ }
+
+ if (interactive) {
+ // The following code to import readline was copied from Python
+ // 2.4.3's Modules/main.c.
+ // Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006
+ // Python Software Foundation; All Rights Reserved
+ // We should only enable this if we're actually using an
+ // interactive prompt.
+ PyObject *v;
+ v = PyImport_ImportModule("readline");
+ if (v == NULL)
+ PyErr_Clear();
+ else
+ Py_DECREF(v);
+
+ PyRun_InteractiveLoop(stdin, "stdin");
+ }
+
+ // clean up Python intepreter.
Py_Finalize();
+}
+
+/// Initialize C++ configuration. Exported to Python via SWIG; invoked
+/// from m5.instantiate().
+void
+initialize()
+{
configStream = simout.find("config.out");
// The configuration database is now complete; start processing it.
@@ -212,8 +274,7 @@ main(int argc, char **argv)
ParamContext::parseAllContexts(inifile);
ParamContext::checkAllContexts();
- // Echo command line and all parameter settings to stats file as well.
- echoCommandLine(argc, argv, *outputStream);
+ // Echo all parameter settings to stats file as well.
ParamContext::showAllContexts(*configStream);
// Any objects that can't connect themselves until after construction should
@@ -244,16 +305,61 @@ main(int argc, char **argv)
// Reset to put the stats in a consistent state.
Stats::reset();
- warn("Entering event queue. Starting simulation...\n");
SimStartup();
- while (!mainEventQueue.empty()) {
+}
+
+
+/** Simulate for num_cycles additional cycles. If num_cycles is -1
+ * (the default), do not limit simulation; some other event must
+ * terminate the loop. Exported to Python via SWIG.
+ * @return The SimLoopExitEvent that caused the loop to exit.
+ */
+SimLoopExitEvent *
+simulate(Tick num_cycles = -1)
+{
+ warn("Entering event queue @ %d. Starting simulation...\n", curTick);
+
+ // Fix up num_cycles. Special default value -1 means simulate
+ // "forever"... schedule event at MaxTick just to be safe.
+ // Otherwise it's a delta for additional cycles to simulate past
+ // curTick, and thus must be non-negative.
+ if (num_cycles == -1)
+ num_cycles = MaxTick;
+ else if (num_cycles < 0)
+ fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles);
+ else
+ num_cycles = curTick + num_cycles;
+
+ Event *limit_event = new SimLoopExitEvent(num_cycles,
+ "simulate() limit reached");
+
+ while (1) {
+ // there should always be at least one event (the SimLoopExitEvent
+ // we just scheduled) in the queue
+ assert(!mainEventQueue.empty());
assert(curTick <= mainEventQueue.nextTick() &&
"event scheduled in the past");
// forward current cycle to the time of the first event on the
// queue
curTick = mainEventQueue.nextTick();
- mainEventQueue.serviceOne();
+ Event *exit_event = mainEventQueue.serviceOne();
+ if (exit_event != NULL) {
+ // hit some kind of exit event; return to Python
+ // event must be subclass of SimLoopExitEvent...
+ SimLoopExitEvent *se_event = dynamic_cast<SimLoopExitEvent *>(exit_event);
+ if (se_event == NULL)
+ panic("Bogus exit event class!");
+
+ // if we didn't hit limit_event, delete it
+ if (se_event != limit_event) {
+ assert(limit_event->scheduled());
+ limit_event->deschedule();
+ delete limit_event;
+ }
+
+ return se_event;
+ }
if (async_event) {
async_event = false;
@@ -273,7 +379,7 @@ main(int argc, char **argv)
if (async_exit) {
async_exit = false;
- new SimExitEvent("User requested STOP");
+ exitSimLoop("user interrupt received");
}
if (async_io || async_alarm) {
@@ -284,11 +390,37 @@ main(int argc, char **argv)
}
}
- // This should never happen... every conceivable way for the
- // simulation to terminate (hit max cycles/insts, signal,
- // simulated system halts/exits) generates an exit event, so we
- // should never run out of events on the queue.
- exitNow("no events on event loop! All CPUs must be idle.", 1);
+ // not reached... only exit is return on SimLoopExitEvent
+}
+
+/**
+ * Queue of C++ callbacks to invoke on simulator exit.
+ */
+CallbackQueue exitCallbacks;
+
+/**
+ * Register an exit callback.
+ */
+void
+registerExitCallback(Callback *callback)
+{
+ exitCallbacks.add(callback);
+}
+
+/**
+ * Do C++ simulator exit processing. Exported to SWIG to be invoked
+ * when simulator terminates via Python's atexit mechanism.
+ */
+void
+doExitCleanup()
+{
+ exitCallbacks.process();
+ exitCallbacks.clear();
+
+ cout.flush();
+
+ ParamContext::cleanupAllContexts();
- return 0;
+ // print simulation stats
+ Stats::DumpNow();
}
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 1533a376d..5080c3ac1 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -50,6 +50,20 @@
#include "sim/syscall_emul.hh"
#include "sim/system.hh"
+#include "arch/isa_specific.hh"
+#if THE_ISA == ALPHA_ISA
+#include "arch/alpha/linux/process.hh"
+#include "arch/alpha/tru64/process.hh"
+#elif THE_ISA == SPARC_ISA
+#include "arch/sparc/linux/process.hh"
+#include "arch/sparc/solaris/process.hh"
+#elif THE_ISA == MIPS_ISA
+#include "arch/mips/linux/process.hh"
+#else
+#error "THE_ISA not set"
+#endif
+
+
using namespace std;
using namespace TheISA;
@@ -362,4 +376,132 @@ LiveProcess::syscall(int64_t callnum, ThreadContext *tc)
desc->doSyscall(callnum, this, tc);
}
-DEFINE_SIM_OBJECT_CLASS_NAME("LiveProcess", LiveProcess);
+LiveProcess *
+LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
+ int stdout_fd, int stderr_fd, std::string executable,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp)
+{
+ LiveProcess *process = NULL;
+
+ ObjectFile *objFile = createObjectFile(executable);
+ if (objFile == NULL) {
+ fatal("Can't load object file %s", executable);
+ }
+
+#if THE_ISA == ALPHA_ISA
+ if (objFile->getArch() != ObjectFile::Alpha)
+ fatal("Object file architecture does not match compiled ISA (Alpha).");
+ switch (objFile->getOpSys()) {
+ case ObjectFile::Tru64:
+ process = new AlphaTru64Process(nm, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp);
+ break;
+
+ case ObjectFile::Linux:
+ process = new AlphaLinuxProcess(nm, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp);
+ break;
+
+ default:
+ fatal("Unknown/unsupported operating system.");
+ }
+#elif THE_ISA == SPARC_ISA
+ if (objFile->getArch() != ObjectFile::SPARC)
+ fatal("Object file architecture does not match compiled ISA (SPARC).");
+ switch (objFile->getOpSys()) {
+ case ObjectFile::Linux:
+ process = new SparcLinuxProcess(nm, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp);
+ break;
+
+
+ case ObjectFile::Solaris:
+ process = new SparcSolarisProcess(nm, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp);
+ break;
+ default:
+ fatal("Unknown/unsupported operating system.");
+ }
+#elif THE_ISA == MIPS_ISA
+ if (objFile->getArch() != ObjectFile::Mips)
+ fatal("Object file architecture does not match compiled ISA (MIPS).");
+ switch (objFile->getOpSys()) {
+ case ObjectFile::Linux:
+ process = new MipsLinuxProcess(nm, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd,
+ argv, envp);
+ break;
+
+ default:
+ fatal("Unknown/unsupported operating system.");
+ }
+#else
+#error "THE_ISA not set"
+#endif
+
+
+ if (process == NULL)
+ fatal("Unknown error creating process object.");
+ return process;
+}
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
+
+ VectorParam<string> cmd;
+ Param<string> executable;
+ Param<string> input;
+ Param<string> output;
+ VectorParam<string> env;
+ SimObjectParam<System *> system;
+
+END_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
+
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess)
+
+ INIT_PARAM(cmd, "command line (executable plus arguments)"),
+ INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
+ INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
+ INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
+ INIT_PARAM(env, "environment settings"),
+ INIT_PARAM(system, "system")
+
+END_INIT_SIM_OBJECT_PARAMS(LiveProcess)
+
+
+CREATE_SIM_OBJECT(LiveProcess)
+{
+ string in = input;
+ string out = output;
+
+ // initialize file descriptors to default: same as simulator
+ int stdin_fd, stdout_fd, stderr_fd;
+
+ if (in == "stdin" || in == "cin")
+ stdin_fd = STDIN_FILENO;
+ else
+ stdin_fd = Process::openInputFile(input);
+
+ if (out == "stdout" || out == "cout")
+ stdout_fd = STDOUT_FILENO;
+ else if (out == "stderr" || out == "cerr")
+ stdout_fd = STDERR_FILENO;
+ else
+ stdout_fd = Process::openOutputFile(out);
+
+ stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
+
+ return LiveProcess::create(getInstanceName(), system,
+ stdin_fd, stdout_fd, stderr_fd,
+ (string)executable == "" ? cmd[0] : executable,
+ cmd, env);
+}
+
+
+REGISTER_SIM_OBJECT("LiveProcess", LiveProcess)
diff --git a/src/sim/process.hh b/src/sim/process.hh
index edbc1e492..763deb100 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -186,6 +186,16 @@ class LiveProcess : public Process
virtual void syscall(int64_t callnum, ThreadContext *tc);
virtual SyscallDesc* getDesc(int callnum) = 0;
+
+ // this function is used to create the LiveProcess object, since
+ // we can't tell which subclass of LiveProcess to use until we
+ // open and look at the object file.
+ static LiveProcess *create(const std::string &nm,
+ System *_system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::string executable,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
};
diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc
index 50d949f53..ae52cdd41 100644
--- a/src/sim/pseudo_inst.cc
+++ b/src/sim/pseudo_inst.cc
@@ -140,14 +140,14 @@ namespace AlphaPseudo
void
m5exit_old(ThreadContext *tc)
{
- SimExit(curTick, "m5_exit_old instruction encountered");
+ exitSimLoop(curTick, "m5_exit_old instruction encountered");
}
void
m5exit(ThreadContext *tc, Tick delay)
{
Tick when = curTick + delay * Clock::Int::ns;
- SimExit(when, "m5_exit instruction encountered");
+ exitSimLoop(when, "m5_exit instruction encountered");
}
void
diff --git a/src/sim/root.cc b/src/sim/root.cc
index 37b768bf0..ec5e2f7e2 100644
--- a/src/sim/root.cc
+++ b/src/sim/root.cc
@@ -40,6 +40,7 @@
#include "sim/builder.hh"
#include "sim/host.hh"
#include "sim/sim_events.hh"
+#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
#include "sim/root.hh"
@@ -99,7 +100,7 @@ void
Root::startup()
{
if (max_tick != 0)
- new SimExitEvent(curTick + max_tick, "reached maximum cycle count");
+ exitSimLoop(curTick + max_tick, "reached maximum cycle count");
if (progress_interval != 0)
new ProgressEvent(&mainEventQueue, progress_interval);
diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc
index 3c86826a6..5270802d1 100644
--- a/src/sim/serialize.cc
+++ b/src/sim/serialize.cc
@@ -248,7 +248,7 @@ Serializable::serializeAll()
assert(Serializable::ckptPrevCount + 1 == Serializable::ckptCount);
Serializable::ckptPrevCount++;
if (ckptMaxCount && ++ckptCount >= ckptMaxCount)
- SimExit(curTick + 1, "Maximum number of checkpoints dropped");
+ exitSimLoop(curTick + 1, "Maximum number of checkpoints dropped");
}
diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc
index 2aa0508ef..b7901832d 100644
--- a/src/sim/sim_events.cc
+++ b/src/sim/sim_events.cc
@@ -45,26 +45,37 @@ using namespace std;
// handle termination event
//
void
-SimExitEvent::process()
+SimLoopExitEvent::process()
{
- // This event does not autodelete because exitNow may be called,
- // and the function will never be allowed to finish.
- if (theQueue() == &mainEventQueue) {
- string _cause = cause;
- int _code = code;
- delete this;
- exitNow(_cause, _code);
- } else {
- new SimExitEvent(cause, code);
+ // if this got scheduled on a different queue (e.g. the committed
+ // instruction queue) then make a corresponding event on the main
+ // queue.
+ if (theQueue() != &mainEventQueue) {
+ exitSimLoop(cause, code);
delete this;
}
+
+ // otherwise do nothing... the IsExitEvent flag takes care of
+ // exiting the simulation loop and returning this object to Python
}
const char *
-SimExitEvent::description()
+SimLoopExitEvent::description()
+{
+ return "simulation loop exit";
+}
+
+void
+exitSimLoop(Tick when, const std::string &message, int exit_code)
+{
+ new SimLoopExitEvent(when, message, exit_code);
+}
+
+void
+exitSimLoop(const std::string &message, int exit_code)
{
- return "simulation termination";
+ exitSimLoop(curTick, message, exit_code);
}
//
@@ -90,7 +101,7 @@ void
CountedExitEvent::process()
{
if (--downCounter == 0) {
- new SimExitEvent(cause, 0);
+ exitSimLoop(cause, 0);
}
}
@@ -119,7 +130,7 @@ CheckSwapEvent::process()
if (swap < 100) {
cerr << "\a\aAborting Simulation! Inadequate swap space!\n\n";
- new SimExitEvent("Lack of swap space");
+ exitSimLoop("Lack of swap space");
}
schedule(curTick + interval);
diff --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh
index 89bf83fc9..4f305ad38 100644
--- a/src/sim/sim_events.hh
+++ b/src/sim/sim_events.hh
@@ -36,7 +36,7 @@
//
// Event to terminate simulation at a particular cycle/instruction
//
-class SimExitEvent : public Event
+class SimLoopExitEvent : public Event
{
private:
// string explaining why we're terminating
@@ -44,24 +44,18 @@ class SimExitEvent : public Event
int code;
public:
- SimExitEvent(const std::string &_cause, int c = 0)
+ SimLoopExitEvent(Tick _when, const std::string &_cause, int c = 0)
: Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause),
code(c)
- { schedule(curTick); }
+ { setFlags(IsExitEvent); schedule(_when); }
- SimExitEvent(Tick _when, const std::string &_cause, int c = 0)
- : Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause),
- code(c)
- { schedule(_when); }
-
- SimExitEvent(EventQueue *q, const std::string &_cause, int c = 0)
+ SimLoopExitEvent(EventQueue *q,
+ Tick _when, const std::string &_cause, int c = 0)
: Event(q, Sim_Exit_Pri), cause(_cause), code(c)
- { schedule(curTick); }
+ { setFlags(IsExitEvent); schedule(_when); }
- SimExitEvent(EventQueue *q, Tick _when, const std::string &_cause,
- int c = 0)
- : Event(q, Sim_Exit_Pri), cause(_cause), code(c)
- { schedule(_when); }
+ std::string getCause() { return cause; }
+ int getCode() { return code; }
void process(); // process event
diff --git a/src/sim/sim_exit.hh b/src/sim/sim_exit.hh
index f1cf4b5fc..545bf4ae0 100644
--- a/src/sim/sim_exit.hh
+++ b/src/sim/sim_exit.hh
@@ -36,12 +36,23 @@
#include "sim/host.hh"
+// forward declaration
class Callback;
+/// Register a callback to be called when Python exits. Defined in
+/// sim/main.cc.
void registerExitCallback(Callback *);
-void exitNow(const std::string &cause, int exit_code);
-void exitNow(const char *cause, int exit_code);
-void SimExit(Tick when, const char *message);
+/// Schedule an event to exit the simulation loop (returning to
+/// Python) at the indicated tick. The message and exit_code
+/// parameters are saved in the SimLoopExitEvent to indicate why the
+/// exit occurred.
+void exitSimLoop(Tick when, const std::string &message, int exit_code = 0);
+
+/// Schedule an event to exit the simulation loop (returning to
+/// Python) at the end of the current cycle (curTick). The message
+/// and exit_code parameters are saved in the SimLoopExitEvent to
+/// indicate why the exit occurred.
+void exitSimLoop(const std::string &cause, int exit_code = 0);
#endif // __SIM_EXIT_HH__
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index 888c133c0..848b6f869 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -27,6 +27,7 @@
*
* Authors: Steve Reinhardt
* Ali Saidi
+ * Korey Sewell
*/
#include <fcntl.h>
@@ -43,7 +44,7 @@
#include "mem/page_table.hh"
#include "sim/process.hh"
-#include "sim/sim_events.hh"
+#include "sim/sim_exit.hh"
using namespace std;
using namespace TheISA;
@@ -91,7 +92,7 @@ SyscallReturn
exitFunc(SyscallDesc *desc, int callnum, Process *process,
ThreadContext *tc)
{
- new SimExitEvent("target called exit()", tc->getSyscallArg(0) & 0xff);
+ exitSimLoop("target called exit()", tc->getSyscallArg(0) & 0xff);
return 1;
}
@@ -341,6 +342,35 @@ fcntlFunc(SyscallDesc *desc, int num, Process *process,
}
SyscallReturn
+fcntl64Func(SyscallDesc *desc, int num, Process *process,
+ ThreadContext *tc)
+{
+ int fd = tc->getSyscallArg(0);
+
+ if (fd < 0 || process->sim_fd(fd) < 0)
+ return -EBADF;
+
+ int cmd = tc->getSyscallArg(1);
+ switch (cmd) {
+ case 33: //F_GETLK64
+ warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd);
+ return -EMFILE;
+
+ case 34: // F_SETLK64
+ case 35: // F_SETLKW64
+ warn("fcntl64(%d, F_SETLK(W)64) not supported, error returned\n", fd);
+ return -EMFILE;
+
+ default:
+ // not sure if this is totally valid, but we'll pass it through
+ // to the underlying OS
+ warn("fcntl64(%d, %d) passed through to host\n", fd, cmd);
+ return fcntl(process->sim_fd(fd), cmd);
+ // return 0;
+ }
+}
+
+SyscallReturn
pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process,
ThreadContext *tc)
{
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 874eaf6a4..f027dbf24 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -27,6 +27,7 @@
*
* Authors: Steve Reinhardt
* Kevin Lim
+ * Korey Sewell
*/
#ifndef __SIM_SYSCALL_EMUL_HH__
@@ -249,6 +250,10 @@ SyscallReturn fchownFunc(SyscallDesc *desc, int num,
SyscallReturn fcntlFunc(SyscallDesc *desc, int num,
Process *process, ThreadContext *tc);
+/// Target fcntl64() handler.
+SyscallReturn fcntl64Func(SyscallDesc *desc, int num,
+ Process *process, ThreadContext *tc);
+
/// Target setuid() handler.
SyscallReturn setuidFunc(SyscallDesc *desc, int num,
Process *p, ThreadContext *tc);
diff --git a/src/sim/system.cc b/src/sim/system.cc
index 7953607d5..91bba85fe 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -119,8 +119,6 @@ System::System(Params *p)
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
@@ -132,8 +130,6 @@ System::~System()
#if FULL_SYSTEM
delete kernelSymtab;
delete kernel;
-
- delete kernelBinning;
#else
panic("System::fixFuncEventAddr needs to be rewritten "
"to work with syscall emulation");
@@ -220,19 +216,9 @@ System::new_page()
#endif
void
-System::regStats()
-{
-#if FULL_SYSTEM
- kernelBinning->regStats(name() + ".kern");
-#endif // FULL_SYSTEM
-}
-
-void
System::serialize(ostream &os)
{
#if FULL_SYSTEM
- kernelBinning->serialize(os);
-
kernelSymtab->serialize("kernel_symtab", os);
#endif // FULL_SYSTEM
}
@@ -242,8 +228,6 @@ void
System::unserialize(Checkpoint *cp, const string &section)
{
#if FULL_SYSTEM
- kernelBinning->unserialize(cp, section);
-
kernelSymtab->unserialize("kernel_symtab", cp, section);
#endif // FULL_SYSTEM
}
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 3a9fdc3d2..059dc92dc 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -56,7 +56,6 @@ class PhysicalMemory;
class Platform;
class GDBListener;
class RemoteGDB;
-namespace Kernel { class Binning; }
#endif
class System : public SimObject
@@ -100,8 +99,6 @@ class System : public SimObject
/** Entry point in the kernel to start at */
Addr kernelEntry;
- Kernel::Binning *kernelBinning;
-
#else
int page_ptr;
@@ -161,9 +158,6 @@ class System : public SimObject
Tick boot_cpu_frequency;
std::string boot_osflags;
uint64_t init_param;
- bool bin;
- std::vector<std::string> binned_fns;
- bool bin_int;
std::string kernel_path;
std::string readfile;
@@ -211,7 +205,6 @@ class System : public SimObject
int registerThreadContext(ThreadContext *tc, int tcIndex);
void replaceThreadContext(ThreadContext *tc, int tcIndex);
- void regStats();
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
diff --git a/src/unittest/stattest.cc b/src/unittest/stattest.cc
index 496d1f672..4e504fde9 100644
--- a/src/unittest/stattest.cc
+++ b/src/unittest/stattest.cc
@@ -50,10 +50,10 @@ Tick ticksPerSecond = ULL(2000000000);
Scalar<> s1;
Scalar<> s2;
Average<> s3;
-Scalar<MainBin> s4;
-Vector<MainBin> s5;
-Distribution<MainBin> s6;
-Vector<MainBin> s7;
+Scalar<> s4;
+Vector<> s5;
+Distribution<> s6;
+Vector<> s7;
AverageVector<> s8;
StandardDeviation<> s9;
AverageDeviation<> s10;
@@ -72,9 +72,6 @@ Value f5;
Formula f6;
Formula f7;
-MainBin bin1("bin1");
-MainBin bin2("bin2");
-
ostream *outputStream = &cout;
double
@@ -303,8 +300,6 @@ main(int argc, char *argv[])
check();
reset();
- bin1.activate();
-
s16[1][0] = 1;
s16[0][1] = 3;
s16[0][0] = 2;
@@ -495,7 +490,6 @@ main(int argc, char *argv[])
s6.sample(8);
s6.sample(9);
- bin2.activate();
s6.sample(10);
s6.sample(10);
s6.sample(10);