summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>2014-09-03 07:42:22 -0400
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>2014-09-03 07:42:22 -0400
commit326662b01b0fbb7fe4e38cec7a96222d2891808b (patch)
tree35bbca1174a6262d3f69dcf729682e1183f8dede
parente1ac9629398027186ef4c2a66772aeff2b4c6792 (diff)
downloadgem5-326662b01b0fbb7fe4e38cec7a96222d2891808b.tar.xz
arch, cpu: Factor out the ExecContext into a proper base class
We currently generate and compile one version of the ISA code per CPU model. This is obviously wasting a lot of resources at compile time. This changeset factors out the interface into a separate ExecContext class, which also serves as documentation for the interface between CPUs and the ISA code. While doing so, this changeset also fixes up interface inconsistencies between the different CPU models. The main argument for using one set of ISA code per CPU model has always been performance as this avoid indirect branches in the generated code. However, this argument does not hold water. Booting Linux on a simulated ARM system running in atomic mode (opt/10.linux-boot/realview-simple-atomic) is actually 2% faster (compiled using clang 3.4) after applying this patch. Additionally, compilation time is decreased by 35%.
-rwxr-xr-xSConstruct12
-rw-r--r--src/arch/SConscript13
-rw-r--r--src/arch/arm/isa/includes.isa1
-rwxr-xr-xsrc/arch/isa_parser.py22
-rw-r--r--src/cpu/SConscript64
-rw-r--r--src/cpu/base_dyn_inst.hh43
-rw-r--r--src/cpu/checker/SConsopts4
-rw-r--r--src/cpu/checker/cpu.hh27
-rw-r--r--src/cpu/exec_context.cc40
-rw-r--r--src/cpu/exec_context.hh278
-rw-r--r--src/cpu/inorder/SConsopts5
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc5
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh46
-rw-r--r--src/cpu/minor/SConsopts5
-rw-r--r--src/cpu/minor/exec_context.hh25
-rw-r--r--src/cpu/nocpu/SConsopts2
-rw-r--r--src/cpu/o3/SConsopts5
-rw-r--r--src/cpu/o3/dyn_inst.hh15
-rw-r--r--src/cpu/ozone/SConsopts8
-rw-r--r--src/cpu/simple/SConsopts10
-rw-r--r--src/cpu/simple/base.hh30
-rw-r--r--src/cpu/simple_thread.cc16
-rw-r--r--src/cpu/static_inst.hh38
23 files changed, 413 insertions, 301 deletions
diff --git a/SConstruct b/SConstruct
index 6250bdd2f..9a64840fc 100755
--- a/SConstruct
+++ b/SConstruct
@@ -1025,17 +1025,10 @@ class CpuModel(object):
# Dict of available CPU model objects. Accessible as CpuModel.dict.
dict = {}
- list = []
- defaults = []
# Constructor. Automatically adds models to CpuModel.dict.
- def __init__(self, name, filename, includes, strings, default=False):
+ def __init__(self, name, default=False):
self.name = name # name of model
- self.filename = filename # filename for output exec code
- self.includes = includes # include files needed in exec file
- # The 'strings' dict holds all the per-CPU symbols we can
- # substitute into templates etc.
- self.strings = strings
# This cpu is enabled by default
self.default = default
@@ -1044,7 +1037,6 @@ class CpuModel(object):
if name in CpuModel.dict:
raise AttributeError, "CpuModel '%s' already registered" % name
CpuModel.dict[name] = self
- CpuModel.list.append(name)
Export('CpuModel')
@@ -1086,7 +1078,7 @@ sticky_vars.AddVariables(
EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
ListVariable('CPU_MODELS', 'CPU models',
sorted(n for n,m in CpuModel.dict.iteritems() if m.default),
- sorted(CpuModel.list)),
+ sorted(CpuModel.dict.keys())),
BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger',
False),
BoolVariable('SS_COMPATIBLE_FP',
diff --git a/src/arch/SConscript b/src/arch/SConscript
index e9b5c5365..31ea0b78f 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -95,13 +95,11 @@ isa_parser = File('isa_parser.py')
# The emitter patches up the sources & targets to include the
# autogenerated files as targets and isa parser itself as a source.
def isa_desc_emitter(target, source, env):
- cpu_models = list(env['CPU_MODELS'])
- cpu_models.append('CheckerCPU')
-
# List the isa parser as a source.
- source += [ isa_parser ]
- # Add in the CPU models.
- source += [ Value(m) for m in cpu_models ]
+ source += [
+ isa_parser,
+ Value("ExecContext"),
+ ]
# Specify different targets depending on if we're running the ISA
# parser for its dependency information, or for the generated files.
@@ -137,8 +135,7 @@ def isa_desc_action_func(target, source, env):
# Skip over the ISA description itself and the parser to the CPU models.
models = [ s.get_contents() for s in source[2:] ]
- cpu_models = [CpuModel.dict[cpu] for cpu in models]
- parser = isa_parser.ISAParser(target[0].dir.abspath, cpu_models)
+ parser = isa_parser.ISAParser(target[0].dir.abspath)
parser.parse_isa_desc(source[0].abspath)
isa_desc_action = MakeAction(isa_desc_action_func, Transform("ISA DESC", 1))
diff --git a/src/arch/arm/isa/includes.isa b/src/arch/arm/isa/includes.isa
index a2ce84345..7328e5307 100644
--- a/src/arch/arm/isa/includes.isa
+++ b/src/arch/arm/isa/includes.isa
@@ -90,6 +90,7 @@ output exec {{
#include "arch/arm/utility.hh"
#include "arch/generic/memhelpers.hh"
#include "base/condcodes.hh"
+#include "cpu/base.hh"
#include "sim/pseudo_inst.hh"
#if defined(linux)
#include <fenv.h>
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index 6aa553588..adadbe14d 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -1178,13 +1178,25 @@ class Stack(list):
#
class ISAParser(Grammar):
- def __init__(self, output_dir, cpu_models):
+ class CpuModel(object):
+ def __init__(self, name, filename, includes, strings):
+ self.name = name
+ self.filename = filename
+ self.includes = includes
+ self.strings = strings
+
+ def __init__(self, output_dir):
super(ISAParser, self).__init__()
self.output_dir = output_dir
self.filename = None # for output file watermarking/scaremongering
- self.cpuModels = cpu_models
+ self.cpuModels = [
+ ISAParser.CpuModel('ExecContext',
+ 'generic_cpu_exec.cc',
+ '#include "cpu/exec_context.hh"',
+ { "CPU_exec_context" : "ExecContext" }),
+ ]
# variable to hold templates
self.templateMap = {}
@@ -2376,8 +2388,6 @@ StaticInstPtr
e.exit(self.fileNameStack)
# Called as script: get args from command line.
-# Args are: <path to cpu_models.py> <isa desc file> <output dir> <cpu models>
+# Args are: <isa desc file> <output dir>
if __name__ == '__main__':
- execfile(sys.argv[1]) # read in CpuModel definitions
- cpu_models = [CpuModel.dict[cpu] for cpu in sys.argv[4:]]
- ISAParser(sys.argv[3], cpu_models).parse_isa_desc(sys.argv[2])
+ ISAParser(sys.argv[2]).parse_isa_desc(sys.argv[1])
diff --git a/src/cpu/SConscript b/src/cpu/SConscript
index 1ea92114a..5d9a48716 100644
--- a/src/cpu/SConscript
+++ b/src/cpu/SConscript
@@ -35,71 +35,8 @@ if env['TARGET_ISA'] == 'null':
Source('intr_control_noisa.cc')
Return()
-#################################################################
-#
-# Generate StaticInst execute() method signatures.
-#
-# There must be one signature for each CPU model compiled in.
-# Since the set of compiled-in models is flexible, we generate a
-# header containing the appropriate set of signatures on the fly.
-#
-#################################################################
-
-# Template for execute() signature.
-exec_sig_template = '''
-virtual Fault execute(%(type)s *xc, Trace::InstRecord *traceData) const = 0;
-virtual Fault eaComp(%(type)s *xc, Trace::InstRecord *traceData) const
-{ panic("eaComp not defined!"); M5_DUMMY_RETURN };
-virtual Fault initiateAcc(%(type)s *xc, Trace::InstRecord *traceData) const
-{ panic("initiateAcc not defined!"); M5_DUMMY_RETURN };
-virtual Fault completeAcc(Packet *pkt, %(type)s *xc,
- Trace::InstRecord *traceData) const
-{ panic("completeAcc not defined!"); M5_DUMMY_RETURN };
-'''
-
-mem_ini_sig_template = '''
-virtual Fault eaComp(%(type)s *xc, Trace::InstRecord *traceData) const
-{ panic("eaComp not defined!"); M5_DUMMY_RETURN };
-virtual Fault initiateAcc(%s *xc, Trace::InstRecord *traceData) const { panic("Not defined!"); M5_DUMMY_RETURN };
-'''
-
-mem_comp_sig_template = '''
-virtual Fault completeAcc(uint8_t *data, %s *xc, Trace::InstRecord *traceData) const { panic("Not defined!"); return NoFault; M5_DUMMY_RETURN };
-'''
-
-# Generate a temporary CPU list, including the CheckerCPU if
-# it's enabled. This isn't used for anything else other than StaticInst
-# headers.
-temp_cpu_list = env['CPU_MODELS'][:]
-temp_cpu_list.append('CheckerCPU')
SimObject('CheckerCPU.py')
-# Generate header.
-def gen_cpu_exec_signatures(target, source, env):
- f = open(str(target[0]), 'w')
- print >> f, '''
-#ifndef __CPU_STATIC_INST_EXEC_SIGS_HH__
-#define __CPU_STATIC_INST_EXEC_SIGS_HH__
-'''
- for cpu in temp_cpu_list:
- xc_type = CpuModel.dict[cpu].strings['CPU_exec_context']
- print >> f, exec_sig_template % { 'type' : xc_type }
- print >> f, '''
-#endif // __CPU_STATIC_INST_EXEC_SIGS_HH__
-'''
-
-# Generate string that gets printed when header is rebuilt
-def gen_sigs_string(target, source, env):
- return " [GENERATE] static_inst_exec_sigs.hh: " \
- + ', '.join(temp_cpu_list)
-
-# Add command to generate header to environment.
-env.Command('static_inst_exec_sigs.hh', (),
- Action(gen_cpu_exec_signatures, gen_sigs_string,
- varlist = temp_cpu_list))
-
-env.Depends('static_inst_exec_sigs.hh', Value(env['CPU_MODELS']))
-
SimObject('BaseCPU.py')
SimObject('FuncUnit.py')
SimObject('ExeTracer.py')
@@ -112,6 +49,7 @@ Source('activity.cc')
Source('base.cc')
Source('cpuevent.cc')
Source('exetrace.cc')
+Source('exec_context.cc')
Source('func_unit.cc')
Source('inteltrace.cc')
Source('intr_control.cc')
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index 08e16d330..9346b69cc 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -56,6 +56,7 @@
#include "config/the_isa.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/o3/comm.hh"
+#include "cpu/exec_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/inst_seq.hh"
#include "cpu/op_class.hh"
@@ -73,7 +74,7 @@
*/
template <class Impl>
-class BaseDynInst : public RefCounted
+class BaseDynInst : public ExecContext, public RefCounted
{
public:
// Typedef for the CPU.
@@ -82,10 +83,6 @@ class BaseDynInst : public RefCounted
// Logical register index type.
typedef TheISA::RegIndex RegIndex;
- // Integer register type.
- typedef TheISA::IntReg IntReg;
- // Floating point register type.
- typedef TheISA::FloatReg FloatReg;
// The DynInstPtr type.
typedef typename Impl::DynInstPtr DynInstPtr;
@@ -634,43 +631,25 @@ class BaseDynInst : public RefCounted
}
/** Records an integer register being set to a value. */
- void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
+ void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
{
setResult<uint64_t>(val);
}
/** Records a CC register being set to a value. */
- void setCCRegOperand(const StaticInst *si, int idx, uint64_t val)
+ void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
{
setResult<uint64_t>(val);
}
/** Records an fp register being set to a value. */
- void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
- int width)
- {
- if (width == 32 || width == 64) {
- setResult<double>(val);
- } else {
- panic("Unsupported width!");
- }
- }
-
- /** Records an fp register being set to a value. */
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
{
setResult<double>(val);
}
/** Records an fp register being set to an integer value. */
- void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val,
- int width)
- {
- setResult<uint64_t>(val);
- }
-
- /** Records an fp register being set to an integer value. */
- void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val)
+ void setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val)
{
setResult<uint64_t>(val);
}
@@ -802,10 +781,10 @@ class BaseDynInst : public RefCounted
bool isSquashedInROB() const { return status[SquashedInROB]; }
/** Read the PC state of this instruction. */
- const TheISA::PCState pcState() const { return pc; }
+ TheISA::PCState pcState() const { return pc; }
/** Set the PC state of this instruction. */
- const void pcState(const TheISA::PCState &val) { pc = val; }
+ void pcState(const TheISA::PCState &val) { pc = val; }
/** Read the PC of this instruction. */
const Addr instAddr() const { return pc.instAddr(); }
@@ -844,10 +823,10 @@ class BaseDynInst : public RefCounted
public:
/** Sets the effective address. */
- void setEA(Addr &ea) { instEffAddr = ea; instFlags[EACalcDone] = true; }
+ void setEA(Addr ea) { instEffAddr = ea; instFlags[EACalcDone] = true; }
/** Returns the effective address. */
- const Addr &getEA() const { return instEffAddr; }
+ Addr getEA() const { return instEffAddr; }
/** Returns whether or not the eff. addr. calculation has been completed. */
bool doneEACalc() { return instFlags[EACalcDone]; }
@@ -869,11 +848,11 @@ class BaseDynInst : public RefCounted
public:
/** Returns the number of consecutive store conditional failures. */
- unsigned readStCondFailures()
+ unsigned int readStCondFailures() const
{ return thread->storeCondFailures; }
/** Sets the number of consecutive store conditional failures. */
- void setStCondFailures(unsigned sc_failures)
+ void setStCondFailures(unsigned int sc_failures)
{ thread->storeCondFailures = sc_failures; }
};
diff --git a/src/cpu/checker/SConsopts b/src/cpu/checker/SConsopts
index 94d8e0e9f..5d676ba1b 100644
--- a/src/cpu/checker/SConsopts
+++ b/src/cpu/checker/SConsopts
@@ -30,6 +30,4 @@
Import('*')
-CpuModel('CheckerCPU', 'checker_cpu_exec.cc',
- '#include "cpu/checker/cpu.hh"',
- { 'CPU_exec_context': 'CheckerCPU' })
+CpuModel('CheckerCPU')
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 9f4c4d58c..bf71dc30e 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -52,6 +52,7 @@
#include "base/statistics.hh"
#include "cpu/base.hh"
#include "cpu/base_dyn_inst.hh"
+#include "cpu/exec_context.hh"
#include "cpu/pc_event.hh"
#include "cpu/simple_thread.hh"
#include "cpu/static_inst.hh"
@@ -86,7 +87,7 @@ class Request;
* checker to be able to correctly verify instructions, even with
* external accesses to the ThreadContext that change state.
*/
-class CheckerCPU : public BaseCPU
+class CheckerCPU : public BaseCPU, public ExecContext
{
protected:
typedef TheISA::MachInst MachInst;
@@ -194,7 +195,7 @@ class CheckerCPU : public BaseCPU
// These functions are only used in CPU models that split
// effective address computation from the actual memory access.
void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); }
- Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); }
+ Addr getEA() const { panic("SimpleCPU::getEA() not implemented\n"); }
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
@@ -207,7 +208,7 @@ class CheckerCPU : public BaseCPU
// storage (which is pretty hard to imagine they would have reason
// to do).
- uint64_t readIntRegOperand(const StaticInst *si, int idx)
+ IntReg readIntRegOperand(const StaticInst *si, int idx)
{
return thread->readIntReg(si->srcRegIdx(idx));
}
@@ -224,7 +225,7 @@ class CheckerCPU : public BaseCPU
return thread->readFloatRegBits(reg_idx);
}
- uint64_t readCCRegOperand(const StaticInst *si, int idx)
+ CCReg readCCRegOperand(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
return thread->readCCReg(reg_idx);
@@ -238,7 +239,7 @@ class CheckerCPU : public BaseCPU
result.push(instRes);
}
- void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
+ void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
{
thread->setIntReg(si->destRegIdx(idx), val);
setResult<uint64_t>(val);
@@ -259,7 +260,7 @@ class CheckerCPU : public BaseCPU
setResult<uint64_t>(val);
}
- void setCCRegOperand(const StaticInst *si, int idx, uint64_t val)
+ void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
thread->setCCReg(reg_idx, val);
@@ -272,7 +273,7 @@ class CheckerCPU : public BaseCPU
thread->setPredicate(val);
}
- TheISA::PCState pcState() { return thread->pcState(); }
+ TheISA::PCState pcState() const { return thread->pcState(); }
void pcState(const TheISA::PCState &val)
{
DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
@@ -322,13 +323,13 @@ class CheckerCPU : public BaseCPU
}
#if THE_ISA == MIPS_ISA
- uint64_t readRegOtherThread(int misc_reg)
+ MiscReg readRegOtherThread(int misc_reg, ThreadID tid)
{
panic("MIPS MT not defined for CheckerCPU.\n");
return 0;
}
- void setRegOtherThread(int misc_reg, const TheISA::MiscReg &val)
+ void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid)
{
panic("MIPS MT not defined for CheckerCPU.\n");
}
@@ -362,7 +363,11 @@ class CheckerCPU : public BaseCPU
Fault writeMem(uint8_t *data, unsigned size,
Addr addr, unsigned flags, uint64_t *res);
- void setStCondFailures(unsigned sc_failures)
+ unsigned int readStCondFailures() const {
+ return thread->readStCondFailures();
+ }
+
+ void setStCondFailures(unsigned int sc_failures)
{}
/////////////////////////////////////////////////////
@@ -371,7 +376,7 @@ class CheckerCPU : public BaseCPU
void wakeup() { }
// Assume that the normal CPU's call to syscall was successful.
// The checker's state would have already been updated by the syscall.
- void syscall(uint64_t callnum) { }
+ void syscall(int64_t callnum) { }
void handleError()
{
diff --git a/src/cpu/exec_context.cc b/src/cpu/exec_context.cc
new file mode 100644
index 000000000..0dde0dc71
--- /dev/null
+++ b/src/cpu/exec_context.cc
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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: Andreas Sandberg
+ */
+
+#include "cpu/exec_context.hh"
diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh
index 2f4d26976..c93f7f32b 100644
--- a/src/cpu/exec_context.hh
+++ b/src/cpu/exec_context.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -26,104 +38,228 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
+ * Andreas Sandberg
*/
-#error "Cannot include this file"
+#ifndef __CPU_EXEC_CONTEXT_HH__
+#define __CPU_EXEC_CONTEXT_HH__
+
+#include "arch/registers.hh"
+#include "base/types.hh"
+#include "config/the_isa.hh"
+#include "cpu/static_inst_fwd.hh"
+#include "cpu/translation.hh"
+#include "sim/fault_fwd.hh"
/**
- * The ExecContext is not a usable class. It is simply here for
- * documentation purposes. It shows the interface that is used by the
- * ISA to access and change CPU state.
+ * The ExecContext is an abstract base class the provides the
+ * interface used by the ISA to manipulate the state of the CPU model.
+ *
+ * Register accessor methods in this class typically provide the index
+ * of the instruction's operand (e.g., 0 or 1), not the architectural
+ * register index, to simplify the implementation of register
+ * renaming. The architectural register index can be found by
+ * indexing into the instruction's own operand index table.
+ *
+ * @note The methods in this class typically take a raw pointer to the
+ * StaticInst is provided instead of a ref-counted StaticInstPtr to
+ * reduce overhead as an argument. This is fine as long as the
+ * implementation doesn't copy the pointer into any long-term storage
+ * (which is pretty hard to imagine they would have reason to do).
*/
class ExecContext {
- // The register accessor methods provide the index of the
- // instruction's operand (e.g., 0 or 1), not the architectural
- // register index, to simplify the implementation of register
- // renaming. We find the architectural register index by indexing
- // into the instruction's own operand index table. Note that a
- // raw pointer to the StaticInst is provided instead of a
- // ref-counted StaticInstPtr to reduce overhead. This is fine as
- // long as these methods don't copy the pointer into any long-term
- // storage (which is pretty hard to imagine they would have reason
- // to do).
+ public:
+ typedef TheISA::IntReg IntReg;
+ typedef TheISA::PCState PCState;
+ typedef TheISA::FloatReg FloatReg;
+ typedef TheISA::FloatRegBits FloatRegBits;
+ typedef TheISA::MiscReg MiscReg;
+
+ typedef TheISA::CCReg CCReg;
+
+ public:
+ /**
+ * @{
+ * @name Integer Register Interfaces
+ *
+ */
/** Reads an integer register. */
- uint64_t readIntRegOperand(const StaticInst *si, int idx);
+ virtual IntReg readIntRegOperand(const StaticInst *si, int idx) = 0;
+
+ /** Sets an integer register to a value. */
+ virtual void setIntRegOperand(const StaticInst *si,
+ int idx, IntReg val) = 0;
+
+ /** @} */
+
+
+ /**
+ * @{
+ * @name Floating Point Register Interfaces
+ */
/** Reads a floating point register of single register width. */
- FloatReg readFloatRegOperand(const StaticInst *si, int idx);
+ virtual FloatReg readFloatRegOperand(const StaticInst *si, int idx) = 0;
/** Reads a floating point register in its binary format, instead
* of by value. */
- FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx);
-
- /** Sets an integer register to a value. */
- void setIntRegOperand(const StaticInst *si, int idx, uint64_t val);
+ virtual FloatRegBits readFloatRegOperandBits(const StaticInst *si,
+ int idx) = 0;
/** Sets a floating point register of single width to a value. */
- void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val);
+ virtual void setFloatRegOperand(const StaticInst *si,
+ int idx, FloatReg val) = 0;
/** Sets the bits of a floating point register of single width
* to a binary value. */
- void setFloatRegOperandBits(const StaticInst *si, int idx,
- FloatRegBits val);
-
- /** Reads the PC. */
- uint64_t readPC();
- /** Reads the NextPC. */
- uint64_t readNextPC();
- /** Reads the Next-NextPC. Only for architectures like SPARC or MIPS. */
- uint64_t readNextNPC();
-
- /** Sets the PC. */
- void setPC(uint64_t val);
- /** Sets the NextPC. */
- void setNextPC(uint64_t val);
- /** Sets the Next-NextPC. Only for architectures like SPARC or MIPS. */
- void setNextNPC(uint64_t val);
-
- /** Reads a miscellaneous register. */
- MiscReg readMiscRegNoEffect(int misc_reg);
-
- /** Reads a miscellaneous register, handling any architectural
- * side effects due to reading that register. */
- MiscReg readMiscReg(int misc_reg);
-
- /** Sets a miscellaneous register. */
- void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
-
- /** Sets a miscellaneous register, handling any architectural
- * side effects due to writing that register. */
- void setMiscReg(int misc_reg, const MiscReg &val);
-
- /** Records the effective address of the instruction. Only valid
- * for memory ops. */
- void setEA(Addr EA);
- /** Returns the effective address of the instruction. Only valid
- * for memory ops. */
- Addr getEA();
+ virtual void setFloatRegOperandBits(const StaticInst *si,
+ int idx, FloatRegBits val) = 0;
- /** Returns a pointer to the ThreadContext. */
- ThreadContext *tcBase();
+ /** @} */
+
+ /**
+ * @{
+ * @name Condition Code Registers
+ */
+ virtual CCReg readCCRegOperand(const StaticInst *si, int idx) = 0;
+ virtual void setCCRegOperand(const StaticInst *si, int idx, CCReg val) = 0;
+ /** @} */
+
+ /**
+ * @{
+ * @name Misc Register Interfaces
+ */
+ virtual MiscReg readMiscRegOperand(const StaticInst *si, int idx) = 0;
+ virtual void setMiscRegOperand(const StaticInst *si,
+ int idx, const MiscReg &val) = 0;
+
+ /**
+ * Reads a miscellaneous register, handling any architectural
+ * side effects due to reading that register.
+ */
+ virtual MiscReg readMiscReg(int misc_reg) = 0;
+
+ /**
+ * Sets a miscellaneous register, handling any architectural
+ * side effects due to writing that register.
+ */
+ virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0;
+
+ /** @} */
+
+ /**
+ * @{
+ * @name PC Control
+ */
+ virtual PCState pcState() const = 0;
+ virtual void pcState(const PCState &val) = 0;
+ /** @} */
+
+ /**
+ * @{
+ * @name Memory Interface
+ */
+ /**
+ * Record the effective address of the instruction.
+ *
+ * @note Only valid for memory ops.
+ */
+ virtual void setEA(Addr EA) = 0;
+ /**
+ * Get the effective address of the instruction.
+ *
+ * @note Only valid for memory ops.
+ */
+ virtual Addr getEA() const = 0;
+
+ virtual Fault readMem(Addr addr, uint8_t *data, unsigned int size,
+ unsigned int flags) = 0;
+
+ virtual Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
+ unsigned int flags, uint64_t *res) = 0;
+
+ /**
+ * Sets the number of consecutive store conditional failures.
+ */
+ virtual void setStCondFailures(unsigned int sc_failures) = 0;
+
+ /**
+ * Returns the number of consecutive store conditional failures.
+ */
+ virtual unsigned int readStCondFailures() const = 0;
- Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
+ /** @} */
- Fault writeMem(uint8_t *data, unsigned size,
- Addr addr, unsigned flags, uint64_t *res);
+ /**
+ * @{
+ * @name SysCall Emulation Interfaces
+ */
+
+ /**
+ * Executes a syscall specified by the callnum.
+ */
+ virtual void syscall(int64_t callnum) = 0;
+
+ /** @} */
+
+ /** Returns a pointer to the ThreadContext. */
+ virtual ThreadContext *tcBase() = 0;
+
+ /**
+ * @{
+ * @name Alpha-Specific Interfaces
+ */
- /** Somewhat Alpha-specific function that handles returning from
- * an error or interrupt. */
- Fault hwrei();
+ /**
+ * Somewhat Alpha-specific function that handles returning from an
+ * error or interrupt.
+ */
+ virtual Fault hwrei() = 0;
/**
* Check for special simulator handling of specific PAL calls. If
* return value is false, actual PAL call will be suppressed.
*/
- bool simPalCheck(int palFunc);
+ virtual bool simPalCheck(int palFunc) = 0;
+
+ /** @} */
+
+ /**
+ * @{
+ * @name ARM-Specific Interfaces
+ */
+
+ virtual bool readPredicate() = 0;
+ virtual void setPredicate(bool val) = 0;
+
+ /** @} */
+
+ /**
+ * @{
+ * @name X86-Specific Interfaces
+ */
+
+ /**
+ * Invalidate a page in the DTLB <i>and</i> ITLB.
+ */
+ virtual void demapPage(Addr vaddr, uint64_t asn) = 0;
- /** Executes a syscall specified by the callnum. */
- void syscall(int64_t callnum);
+ /** @} */
- /** Finish a DTB address translation. */
- void finishTranslation(WholeTranslationState *state);
+ /**
+ * @{
+ * @name MIPS-Specific Interfaces
+ */
+
+#if THE_ISA == MIPS_ISA
+ virtual MiscReg readRegOtherThread(int regIdx,
+ ThreadID tid = InvalidThreadID) = 0;
+ virtual void setRegOtherThread(int regIdx, MiscReg val,
+ ThreadID tid = InvalidThreadID) = 0;
+#endif
+
+ /** @} */
};
+
+#endif // __CPU_EXEC_CONTEXT_HH__
diff --git a/src/cpu/inorder/SConsopts b/src/cpu/inorder/SConsopts
index 709051407..f6b8917c6 100644
--- a/src/cpu/inorder/SConsopts
+++ b/src/cpu/inorder/SConsopts
@@ -30,7 +30,4 @@
Import('*')
-CpuModel('InOrderCPU', 'inorder_cpu_exec.cc',
- '#include "cpu/inorder/inorder_dyn_inst.hh"',
- { 'CPU_exec_context': 'InOrderDynInst' },
- default=True)
+CpuModel('InOrderCPU', default=True)
diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc
index 86dbdf97c..d0d308f7a 100644
--- a/src/cpu/inorder/inorder_dyn_inst.cc
+++ b/src/cpu/inorder/inorder_dyn_inst.cc
@@ -469,7 +469,7 @@ InOrderDynInst::setMiscRegOperand(const StaticInst *si, int idx,
}
MiscReg
-InOrderDynInst::readRegOtherThread(unsigned reg_idx, ThreadID tid)
+InOrderDynInst::readRegOtherThread(int reg_idx, ThreadID tid)
{
if (tid == -1) {
tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
@@ -544,8 +544,7 @@ InOrderDynInst::setMiscReg(int misc_reg, const MiscReg &val)
}
void
-InOrderDynInst::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
- ThreadID tid)
+InOrderDynInst::setRegOtherThread(int reg_idx, MiscReg val, ThreadID tid)
{
if (tid == InvalidThreadID) {
tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh
index 578fd604a..759da4b04 100644
--- a/src/cpu/inorder/inorder_dyn_inst.hh
+++ b/src/cpu/inorder/inorder_dyn_inst.hh
@@ -45,6 +45,7 @@
#include "base/trace.hh"
#include "base/types.hh"
#include "config/the_isa.hh"
+#include "cpu/exec_context.hh"
#include "cpu/inorder/inorder_trace.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/resource.hh"
@@ -73,7 +74,7 @@
class ResourceRequest;
class Packet;
-class InOrderDynInst : public RefCounted
+class InOrderDynInst : public ExecContext, public RefCounted
{
public:
// Binary machine instruction type.
@@ -543,7 +544,7 @@ class InOrderDynInst : public RefCounted
//
////////////////////////////////////////////////////////////
/** Read the PC of this instruction. */
- const TheISA::PCState &pcState() const { return pc; }
+ TheISA::PCState pcState() const { return pc; }
/** Sets the PC of this instruction. */
void pcState(const TheISA::PCState &_pc) { pc = _pc; }
@@ -649,10 +650,10 @@ class InOrderDynInst : public RefCounted
{ return memAddr; }
/** Sets the effective address. */
- void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; }
+ void setEA(Addr ea) { instEffAddr = ea; eaCalcDone = true; }
/** Returns the effective address. */
- const Addr &getEA() const { return instEffAddr; }
+ Addr getEA() const { return instEffAddr; }
/** Returns whether or not the eff. addr. calculation has been completed.*/
bool doneEACalc() { return eaCalcDone; }
@@ -854,7 +855,10 @@ class InOrderDynInst : public RefCounted
* language (which is why the name isnt readIntSrc(...)) Note: That
* the source reg. value is set using the setSrcReg() function.
*/
- IntReg readIntRegOperand(const StaticInst *si, int idx, ThreadID tid = 0);
+ IntReg readIntRegOperand(const StaticInst *si, int idx, ThreadID tid);
+ IntReg readIntRegOperand(const StaticInst *si, int idx) {
+ return readIntRegOperand(si, idx, 0);
+ }
FloatReg readFloatRegOperand(const StaticInst *si, int idx);
TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx);
MiscReg readMiscReg(int misc_reg);
@@ -899,24 +903,21 @@ class InOrderDynInst : public RefCounted
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val);
void setFloatRegOperandBits(const StaticInst *si, int idx,
TheISA::FloatRegBits val);
- void setCCRegOperand(const StaticInst *si, int idx, CCReg val);
void setMiscReg(int misc_reg, const MiscReg &val);
void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val);
void setMiscRegOperandNoEffect(const StaticInst *si, int idx,
const MiscReg &val);
- virtual uint64_t readRegOtherThread(unsigned idx,
- ThreadID tid = InvalidThreadID);
- virtual void setRegOtherThread(unsigned idx, const uint64_t &val,
- ThreadID tid = InvalidThreadID);
+ MiscReg readRegOtherThread(int idx, ThreadID tid);
+ void setRegOtherThread(int idx, MiscReg val, ThreadID tid);
/** Returns the number of consecutive store conditional failures. */
- unsigned readStCondFailures()
+ unsigned int readStCondFailures() const
{ return thread->storeCondFailures; }
/** Sets the number of consecutive store conditional failures. */
- void setStCondFailures(unsigned sc_failures)
+ void setStCondFailures(unsigned int sc_failures)
{ thread->storeCondFailures = sc_failures; }
//////////////////////////////////////////////////////////////
@@ -1063,6 +1064,27 @@ class InOrderDynInst : public RefCounted
void dump(std::string &outstring);
//inline int curCount() { return curCount(); }
+
+
+ CCReg readCCRegOperand(const StaticInst *si, int idx) {
+ panic("readCCRegOperand unimplemented");
+ }
+
+ void setCCRegOperand(const StaticInst *si, int idx, CCReg val) {
+ panic("setCCRegOperand unimplemented");
+ }
+
+ void setPredicate(bool val) {
+ panic("setPredicate unimplemented");
+ }
+
+ bool readPredicate() {
+ panic("readPredicate unimplemented");
+ }
+
+ void demapPage(Addr vaddr, uint64_t asn) {
+ panic("demapPage unimplemented");
+ }
};
diff --git a/src/cpu/minor/SConsopts b/src/cpu/minor/SConsopts
index 68c420779..b74e15730 100644
--- a/src/cpu/minor/SConsopts
+++ b/src/cpu/minor/SConsopts
@@ -39,7 +39,4 @@
Import('*')
-CpuModel('MinorCPU', 'minor_cpu_exec.cc',
- '#include "cpu/minor/exec_context.hh"',
- { 'CPU_exec_context': 'Minor::ExecContext' },
- default=True)
+CpuModel('MinorCPU', default=True)
diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh
index df909a95c..f1143498e 100644
--- a/src/cpu/minor/exec_context.hh
+++ b/src/cpu/minor/exec_context.hh
@@ -53,6 +53,7 @@
#ifndef __CPU_MINOR_EXEC_CONTEXT_HH__
#define __CPU_MINOR_EXEC_CONTEXT_HH__
+#include "cpu/exec_context.hh"
#include "cpu/minor/execute.hh"
#include "cpu/minor/pipeline.hh"
#include "cpu/base.hh"
@@ -69,7 +70,7 @@ class Execute;
* separates that interface from other classes such as Pipeline, MinorCPU
* and DynMinorInst and makes it easier to see what state is accessed by it.
*/
-class ExecContext
+class ExecContext : public ::ExecContext
{
public:
MinorCPU &cpu;
@@ -119,7 +120,7 @@ class ExecContext
return NoFault;
}
- uint64_t
+ IntReg
readIntRegOperand(const StaticInst *si, int idx)
{
return thread.readIntReg(si->srcRegIdx(idx));
@@ -140,7 +141,7 @@ class ExecContext
}
void
- setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
+ setIntRegOperand(const StaticInst *si, int idx, IntReg val)
{
thread.setIntReg(si->destRegIdx(idx), val);
}
@@ -174,7 +175,7 @@ class ExecContext
}
TheISA::PCState
- pcState()
+ pcState() const
{
return thread.pcState();
}
@@ -250,12 +251,8 @@ class ExecContext
ThreadContext *tcBase() { return thread.getTC(); }
/* @todo, should make stCondFailures persistent somewhere */
- unsigned int readStCondFailures() { return 0; }
- unsigned int
- setStCondFailures(unsigned int st_cond_failures)
- {
- return 0;
- }
+ unsigned int readStCondFailures() const { return 0; }
+ void setStCondFailures(unsigned int st_cond_failures) {}
int contextId() { return thread.contextId(); }
/* ISA-specific (or at least currently ISA singleton) functions */
@@ -295,7 +292,7 @@ class ExecContext
}
/* ALPHA/POWER: Effective address storage */
- void setEA(Addr &ea)
+ void setEA(Addr ea)
{
inst->ea = ea;
}
@@ -303,14 +300,14 @@ class ExecContext
BaseCPU *getCpuPtr() { return &cpu; }
/* POWER: Effective address storage */
- Addr getEA()
+ Addr getEA() const
{
return inst->ea;
}
/* MIPS: other thread register reading/writing */
uint64_t
- readRegOtherThread(unsigned idx, ThreadID tid = InvalidThreadID)
+ readRegOtherThread(int idx, ThreadID tid = InvalidThreadID)
{
SimpleThread *other_thread = (tid == InvalidThreadID
? &thread : cpu.threads[tid]);
@@ -327,7 +324,7 @@ class ExecContext
}
void
- setRegOtherThread(unsigned idx, const TheISA::MiscReg &val,
+ setRegOtherThread(int idx, const TheISA::MiscReg &val,
ThreadID tid = InvalidThreadID)
{
SimpleThread *other_thread = (tid == InvalidThreadID
diff --git a/src/cpu/nocpu/SConsopts b/src/cpu/nocpu/SConsopts
index 0baef0a82..40bf503ea 100644
--- a/src/cpu/nocpu/SConsopts
+++ b/src/cpu/nocpu/SConsopts
@@ -1,4 +1,4 @@
Import('*')
-CpuModel('no', '', '', { '': '' })
+CpuModel('no')
diff --git a/src/cpu/o3/SConsopts b/src/cpu/o3/SConsopts
index b780f6b2a..dfee888e5 100644
--- a/src/cpu/o3/SConsopts
+++ b/src/cpu/o3/SConsopts
@@ -30,7 +30,4 @@
Import('*')
-CpuModel('O3CPU', 'o3_cpu_exec.cc',
- '#include "cpu/o3/isa_specific.hh"',
- { 'CPU_exec_context': 'O3DynInst' },
- default=True)
+CpuModel('O3CPU', default=True)
diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh
index 76bd8b291..52ea1101a 100644
--- a/src/cpu/o3/dyn_inst.hh
+++ b/src/cpu/o3/dyn_inst.hh
@@ -71,9 +71,8 @@ class BaseO3DynInst : public BaseDynInst<Impl>
typedef TheISA::IntReg IntReg;
typedef TheISA::FloatReg FloatReg;
typedef TheISA::FloatRegBits FloatRegBits;
-#ifdef ISA_HAS_CC_REGS
typedef TheISA::CCReg CCReg;
-#endif
+
/** Misc register index type. */
typedef TheISA::MiscReg MiscReg;
@@ -250,7 +249,7 @@ class BaseO3DynInst : public BaseDynInst<Impl>
// storage (which is pretty hard to imagine they would have reason
// to do).
- uint64_t readIntRegOperand(const StaticInst *si, int idx)
+ IntReg readIntRegOperand(const StaticInst *si, int idx)
{
return this->cpu->readIntReg(this->_srcRegIdx[idx]);
}
@@ -265,7 +264,7 @@ class BaseO3DynInst : public BaseDynInst<Impl>
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
}
- uint64_t readCCRegOperand(const StaticInst *si, int idx)
+ CCReg readCCRegOperand(const StaticInst *si, int idx)
{
return this->cpu->readCCReg(this->_srcRegIdx[idx]);
}
@@ -273,7 +272,7 @@ class BaseO3DynInst : public BaseDynInst<Impl>
/** @todo: Make results into arrays so they can handle multiple dest
* registers.
*/
- void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
+ void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
{
this->cpu->setIntReg(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
@@ -292,20 +291,20 @@ class BaseO3DynInst : public BaseDynInst<Impl>
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
}
- void setCCRegOperand(const StaticInst *si, int idx, uint64_t val)
+ void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
{
this->cpu->setCCReg(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setCCRegOperand(si, idx, val);
}
#if THE_ISA == MIPS_ISA
- uint64_t readRegOtherThread(int misc_reg)
+ MiscReg readRegOtherThread(int misc_reg, ThreadID tid)
{
panic("MIPS MT not defined for O3 CPU.\n");
return 0;
}
- void setRegOtherThread(int misc_reg, const TheISA::MiscReg &val)
+ void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid)
{
panic("MIPS MT not defined for O3 CPU.\n");
}
diff --git a/src/cpu/ozone/SConsopts b/src/cpu/ozone/SConsopts
index adfda63a9..c1ee00ec3 100644
--- a/src/cpu/ozone/SConsopts
+++ b/src/cpu/ozone/SConsopts
@@ -30,10 +30,6 @@
Import('*')
-CpuModel('OzoneSimpleCPU', 'ozone_simple_exec.cc',
- '#include "cpu/ozone/dyn_inst.hh"',
- { 'CPU_exec_context': 'OzoneDynInst<SimpleImpl>' })
-CpuModel('OzoneCPU', 'ozone_exec.cc',
- '#include "cpu/ozone/dyn_inst.hh"',
- { 'CPU_exec_context': 'OzoneDynInst<OzoneImpl>' })
+CpuModel('OzoneSimpleCPU')
+CpuModel('OzoneCPU')
diff --git a/src/cpu/simple/SConsopts b/src/cpu/simple/SConsopts
index ab84144af..9c99a818f 100644
--- a/src/cpu/simple/SConsopts
+++ b/src/cpu/simple/SConsopts
@@ -30,11 +30,5 @@
Import('*')
-CpuModel('AtomicSimpleCPU', 'atomic_simple_cpu_exec.cc',
- '#include "cpu/simple/atomic.hh"',
- { 'CPU_exec_context': 'AtomicSimpleCPU' },
- default=True)
-CpuModel('TimingSimpleCPU', 'timing_simple_cpu_exec.cc',
- '#include "cpu/simple/timing.hh"',
- { 'CPU_exec_context': 'TimingSimpleCPU' },
- default=True)
+CpuModel('AtomicSimpleCPU', default=True)
+CpuModel('TimingSimpleCPU', default=True)
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index 47034c300..3755a94a9 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -50,6 +50,7 @@
#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/checker/cpu.hh"
+#include "cpu/exec_context.hh"
#include "cpu/pc_event.hh"
#include "cpu/simple_thread.hh"
#include "cpu/static_inst.hh"
@@ -79,7 +80,7 @@ namespace Trace {
struct BaseSimpleCPUParams;
class BPredUnit;
-class BaseSimpleCPU : public BaseCPU
+class BaseSimpleCPU : public BaseCPU, public ExecContext
{
protected:
typedef TheISA::MiscReg MiscReg;
@@ -293,8 +294,7 @@ class BaseSimpleCPU : public BaseCPU
// These functions are only used in CPU models that split
// effective address computation from the actual memory access.
void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
- Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n");
- M5_DUMMY_RETURN}
+ Addr getEA() const { panic("BaseSimpleCPU::getEA() not implemented\n"); }
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
@@ -307,7 +307,7 @@ class BaseSimpleCPU : public BaseCPU
// storage (which is pretty hard to imagine they would have reason
// to do).
- uint64_t readIntRegOperand(const StaticInst *si, int idx)
+ IntReg readIntRegOperand(const StaticInst *si, int idx)
{
numIntRegReads++;
return thread->readIntReg(si->srcRegIdx(idx));
@@ -334,7 +334,7 @@ class BaseSimpleCPU : public BaseCPU
return thread->readCCReg(reg_idx);
}
- void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
+ void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
{
numIntRegWrites++;
thread->setIntReg(si->destRegIdx(idx), val);
@@ -370,7 +370,7 @@ class BaseSimpleCPU : public BaseCPU
traceData->setPredicate(val);
}
}
- TheISA::PCState pcState() { return thread->pcState(); }
+ TheISA::PCState pcState() const { return thread->pcState(); }
void pcState(const TheISA::PCState &val) { thread->pcState(val); }
Addr instAddr() { return thread->instAddr(); }
Addr nextInstAddr() { return thread->nextInstAddr(); }
@@ -423,26 +423,26 @@ class BaseSimpleCPU : public BaseCPU
thread->demapDataPage(vaddr, asn);
}
- unsigned readStCondFailures() {
+ unsigned int readStCondFailures() const {
return thread->readStCondFailures();
}
- void setStCondFailures(unsigned sc_failures) {
+ void setStCondFailures(unsigned int sc_failures) {
thread->setStCondFailures(sc_failures);
}
- MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
- {
+ MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
+ {
panic("Simple CPU models do not support multithreaded "
"register access.\n");
- }
+ }
- void setRegOtherThread(int regIdx, const MiscReg &val,
- ThreadID tid = InvalidThreadID)
- {
+ void setRegOtherThread(int regIdx, MiscReg val,
+ ThreadID tid = InvalidThreadID)
+ {
panic("Simple CPU models do not support multithreaded "
"register access.\n");
- }
+ }
//Fault CacheOp(uint8_t Op, Addr EA);
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index de01124e0..4e2e70e63 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -50,6 +50,7 @@
#include "mem/fs_translating_port_proxy.hh"
#include "mem/se_translating_port_proxy.hh"
#include "params/BaseCPU.hh"
+#include "sim/faults.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"
#include "sim/serialize.hh"
@@ -213,3 +214,18 @@ SimpleThread::copyArchRegs(ThreadContext *src_tc)
TheISA::copyRegs(src_tc, tc);
}
+// The following methods are defined in src/arch/alpha/ev5.cc for
+// Alpha.
+#if THE_ISA != ALPHA_ISA
+Fault
+SimpleThread::hwrei()
+{
+ return NoFault;
+}
+
+bool
+SimpleThread::simPalCheck(int palFunc)
+{
+ return true;
+}
+#endif
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 375b7d0ba..c4dd3a6b5 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -50,19 +50,7 @@
// forward declarations
class Packet;
-struct O3CPUImpl;
-template <class Impl> class BaseO3DynInst;
-typedef BaseO3DynInst<O3CPUImpl> O3DynInst;
-class InOrderDynInst;
-
-class CheckerCPU;
-class AtomicSimpleCPU;
-class TimingSimpleCPU;
-class InorderCPU;
-namespace Minor
-{
- class ExecContext;
-};
+class ExecContext;
class SymbolTable;
@@ -267,11 +255,25 @@ class StaticInst : public RefCounted, public StaticInstFlags
public:
virtual ~StaticInst();
-/**
- * The execute() signatures are auto-generated by scons based on the
- * set of CPU models we are compiling in today.
- */
-#include "cpu/static_inst_exec_sigs.hh"
+ virtual Fault execute(ExecContext *xc,
+ Trace::InstRecord *traceData) const = 0;
+ virtual Fault eaComp(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("eaComp not defined!");
+ }
+
+ virtual Fault initiateAcc(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("initiateAcc not defined!");
+ }
+
+ virtual Fault completeAcc(Packet *pkt, ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("completeAcc not defined!");
+ }
virtual void advancePC(TheISA::PCState &pcState) const = 0;