arch, cpu: Factor out the ExecContext into a proper base class
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>
Wed, 3 Sep 2014 11:42:22 +0000 (07:42 -0400)
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>
Wed, 3 Sep 2014 11:42:22 +0000 (07:42 -0400)
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%.

23 files changed:
SConstruct
src/arch/SConscript
src/arch/arm/isa/includes.isa
src/arch/isa_parser.py
src/cpu/SConscript
src/cpu/base_dyn_inst.hh
src/cpu/checker/SConsopts
src/cpu/checker/cpu.hh
src/cpu/exec_context.cc [new file with mode: 0644]
src/cpu/exec_context.hh
src/cpu/inorder/SConsopts
src/cpu/inorder/inorder_dyn_inst.cc
src/cpu/inorder/inorder_dyn_inst.hh
src/cpu/minor/SConsopts
src/cpu/minor/exec_context.hh
src/cpu/nocpu/SConsopts
src/cpu/o3/SConsopts
src/cpu/o3/dyn_inst.hh
src/cpu/ozone/SConsopts
src/cpu/simple/SConsopts
src/cpu/simple/base.hh
src/cpu/simple_thread.cc
src/cpu/static_inst.hh

index 6250bdd2f6ec710d9f169706b4005aaefa97b5cb..9a64840fc1b4e1fdccaf65bc7e230f8e9b43a63b 100755 (executable)
@@ -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',
index e9b5c5365f5487495921c8095b65f7950cb4b390..31ea0b78fcc75db0683ec221d464d0cbb812231f 100644 (file)
@@ -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))
 
index a2ce843456843a3bbacd5e527649d4da32ef8bf1..7328e530718cb37d76208c29cde0f84833886bc8 100644 (file)
@@ -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>
index 6aa5535889d64e61476a37adae601f4a2c232a23..adadbe14d9fc18ad4555a8a69f28298c1e42a920 100755 (executable)
@@ -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])
index 1ea92114a8754d3d1b4e275f88ab8e57646facf3..5d9a48716e14fb65df88abf9e806960337a116c7 100644 (file)
@@ -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')
index 08e16d330495a67540752079d4857d6ed49017d8..9346b69cc42b2acfa0303b5087934bc0803f8e6b 100644 (file)
@@ -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,28 +631,17 @@ 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)
     {
@@ -663,14 +649,7 @@ class BaseDynInst : public RefCounted
     }
 
     /** 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; }
 };
 
index 94d8e0e9f6a2a39d2c1e268e9bae15bd3871f717..5d676ba1b1bb04e4da0f8da360feed9c189a3e05 100644 (file)
@@ -30,6 +30,4 @@
 
 Import('*')
 
-CpuModel('CheckerCPU', 'checker_cpu_exec.cc',
-         '#include "cpu/checker/cpu.hh"',
-         { 'CPU_exec_context': 'CheckerCPU' })
+CpuModel('CheckerCPU')
index 9f4c4d58c995c9edf12c69515d8c4d66e6d47cc6..bf71dc30e6f7933a818b6ef1cd0f8a15cd1ad3dc 100644 (file)
@@ -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 (file)
index 0000000..0dde0dc
--- /dev/null
@@ -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"
index 2f4d26976914c2b12e6ff8e84f565db9f6edcc33..c93f7f32be76b957a674de133e2ac2fb1ae48b12 100644 (file)
@@ -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.
  *
  * 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__
index 70905140705085c2e1accd31d287410e2a29826d..f6b8917c68540fcadc26db2f156950a6cc443ef5 100644 (file)
@@ -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)
index 86dbdf97c45957e087b4d30ea36ea28be50db734..d0d308f7a8c5ac7da68b3fae07547bfc88ada020 100644 (file)
@@ -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));
index 578fd604af8758f139116d68da02d804fa76fd22..759da4b04b5e982e43a79d8d3c70c385ca50fca7 100644 (file)
@@ -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");
+    }
 };
 
 
index 68c42077932368cd279aea6a4bc9acf96974202c..b74e15730a8256fad7c17a7dab40bc7af6f3920c 100644 (file)
@@ -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)
index df909a95c3885de48f90ad3a0fb56572dfb71803..f1143498e7bfdecff3d103e41e1fb2fb782a1217 100644 (file)
@@ -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
index 0baef0a82b5af18da651bf8933536c768280e9e2..40bf503ea184b2029461247bf2fc9ad3ba371f4e 100644 (file)
@@ -1,4 +1,4 @@
 
 Import('*')
 
-CpuModel('no', '', '', { '': '' })
+CpuModel('no')
index b780f6b2af1555a7a2837c809e6e3b2429545217..dfee888e58ca0c9537156a25cd36c6d2fc28f7ac 100644 (file)
@@ -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)
index 76bd8b29108bfec19d27d500fa0439cbbd9601eb..52ea1101a15a690d0a3ce064bee5f8188214a4e2 100644 (file)
@@ -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");
     }
index adfda63a949dca640a4864bade93c61375b9b12d..c1ee00ec3b8f815df0f918df8fe0e28a3f00d511 100644 (file)
 
 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')
 
index ab84144af4468183b3dc7dc2075ce5c2449e2f1b..9c99a818f28d2d554f7a3579d23628ef7a936f19 100644 (file)
 
 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)
index 47034c300c9555a554d31af72df073898f1a4268..3755a94a94276b8324ca3f53cc7534c0ccd9f7d6 100644 (file)
@@ -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);
 
index de01124e035a8453a9bf8fa177fd47b445b3f39c..4e2e70e637da15d811201839800bce92bec27328 100644 (file)
@@ -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
index 375b7d0bacad8c5b7e20d09b882edf3d5572b514..c4dd3a6b51f9af86fc1ff0e8649098c51d6031ab 100644 (file)
 // 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;