summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/SConscript116
-rw-r--r--src/cpu/base.cc35
-rw-r--r--src/cpu/base.hh12
-rw-r--r--src/cpu/checker/cpu.cc4
-rw-r--r--src/cpu/checker/cpu.hh16
-rw-r--r--src/cpu/checker/cpu_impl.hh10
-rw-r--r--src/cpu/checker/thread_context.hh16
-rw-r--r--src/cpu/exec_context.hh8
-rw-r--r--src/cpu/exetrace.cc388
-rw-r--r--src/cpu/exetrace.hh68
-rw-r--r--src/cpu/intr_control.cc22
-rw-r--r--src/cpu/intr_control.hh4
-rw-r--r--src/cpu/memtest/SConscript34
-rw-r--r--src/cpu/memtest/memtest.cc12
-rwxr-xr-xsrc/cpu/o3/SConscript86
-rw-r--r--src/cpu/o3/SConsopts34
-rw-r--r--src/cpu/o3/alpha/cpu.hh8
-rw-r--r--src/cpu/o3/alpha/cpu_impl.hh18
-rw-r--r--src/cpu/o3/alpha/dyn_inst.hh32
-rw-r--r--src/cpu/o3/alpha/dyn_inst_impl.hh2
-rw-r--r--src/cpu/o3/commit_impl.hh3
-rw-r--r--src/cpu/o3/cpu.cc41
-rw-r--r--src/cpu/o3/cpu.hh4
-rw-r--r--src/cpu/o3/dyn_inst.hh4
-rw-r--r--src/cpu/o3/fetch.hh4
-rw-r--r--src/cpu/o3/fetch_impl.hh16
-rw-r--r--src/cpu/o3/inst_queue_impl.hh2
-rw-r--r--src/cpu/o3/lsq.hh7
-rw-r--r--src/cpu/o3/lsq_impl.hh13
-rw-r--r--src/cpu/o3/lsq_unit.hh5
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh3
-rwxr-xr-xsrc/cpu/o3/mips/cpu.hh8
-rw-r--r--src/cpu/o3/mips/cpu_impl.hh16
-rwxr-xr-xsrc/cpu/o3/mips/dyn_inst.hh16
-rw-r--r--src/cpu/o3/regfile.hh16
-rw-r--r--src/cpu/o3/sparc/cpu.hh8
-rw-r--r--src/cpu/o3/sparc/cpu_impl.hh16
-rw-r--r--src/cpu/o3/sparc/dyn_inst.hh32
-rwxr-xr-xsrc/cpu/o3/thread_context.hh12
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh10
-rw-r--r--src/cpu/ozone/SConscript45
-rw-r--r--src/cpu/ozone/SConsopts33
-rw-r--r--src/cpu/ozone/cpu.hh6
-rw-r--r--src/cpu/ozone/cpu_impl.hh18
-rw-r--r--src/cpu/ozone/dyn_inst.hh6
-rw-r--r--src/cpu/ozone/dyn_inst_impl.hh18
-rw-r--r--src/cpu/ozone/inorder_back_end_impl.hh14
-rw-r--r--src/cpu/ozone/inst_queue_impl.hh2
-rw-r--r--src/cpu/ozone/lw_back_end_impl.hh2
-rw-r--r--src/cpu/ozone/lw_lsq_impl.hh6
-rw-r--r--src/cpu/ozone/thread_state.hh16
-rw-r--r--src/cpu/pc_event.cc4
-rw-r--r--src/cpu/simple/SConscript43
-rw-r--r--src/cpu/simple/SConsopts34
-rw-r--r--src/cpu/simple/atomic.cc105
-rw-r--r--src/cpu/simple/atomic.hh18
-rw-r--r--src/cpu/simple/base.cc62
-rw-r--r--src/cpu/simple/base.hh47
-rw-r--r--src/cpu/simple/timing.cc87
-rw-r--r--src/cpu/simple/timing.hh2
-rw-r--r--src/cpu/simple_thread.cc2
-rw-r--r--src/cpu/simple_thread.hh16
-rw-r--r--src/cpu/static_inst.cc2
-rw-r--r--src/cpu/static_inst.hh6
-rw-r--r--src/cpu/thread_context.hh21
-rw-r--r--src/cpu/thread_state.cc10
-rw-r--r--src/cpu/trace/SConscript40
67 files changed, 1073 insertions, 753 deletions
diff --git a/src/cpu/SConscript b/src/cpu/SConscript
index 4d4b7574c..1c2278f6f 100644
--- a/src/cpu/SConscript
+++ b/src/cpu/SConscript
@@ -28,11 +28,7 @@
#
# Authors: Steve Reinhardt
-import os
-import os.path
-
-# Import build environment variable from SConstruct.
-Import('env')
+Import('*')
#################################################################
#
@@ -107,89 +103,24 @@ env.Depends('static_inst_exec_sigs.hh', Value(env['CPU_MODELS']))
# and one of these are not being used.
CheckerSupportedCPUList = ['O3CPU', 'OzoneCPU']
-#################################################################
-#
-# Include CPU-model-specific files based on set of models
-# specified in CPU_MODELS build option.
-#
-#################################################################
-
-# Keep a list of CPU models that support SMT
-env['SMT_CPU_MODELS'] = []
-
-sources = []
-
-need_simple_base = False
-if 'AtomicSimpleCPU' in env['CPU_MODELS']:
- need_simple_base = True
- sources += Split('simple/atomic.cc')
-
-if 'TimingSimpleCPU' in env['CPU_MODELS']:
- need_simple_base = True
- sources += Split('simple/timing.cc')
-
-if need_simple_base:
- sources += Split('simple/base.cc')
-
-if 'FastCPU' in env['CPU_MODELS']:
- sources += Split('fast/cpu.cc')
-
-need_bp_unit = False
-if 'O3CPU' in env['CPU_MODELS']:
- need_bp_unit = True
- sources += SConscript('o3/SConscript', exports = 'env')
- sources += Split('''
- o3/base_dyn_inst.cc
- o3/bpred_unit.cc
- o3/commit.cc
- o3/decode.cc
- o3/fetch.cc
- o3/free_list.cc
- o3/fu_pool.cc
- o3/cpu.cc
- o3/iew.cc
- o3/inst_queue.cc
- o3/lsq_unit.cc
- o3/lsq.cc
- o3/mem_dep_unit.cc
- o3/rename.cc
- o3/rename_map.cc
- o3/rob.cc
- o3/scoreboard.cc
- o3/store_set.cc
- ''')
- sources += Split('memtest/memtest.cc')
- if env['USE_CHECKER']:
- sources += Split('o3/checker_builder.cc')
- else:
- env['SMT_CPU_MODELS'].append('O3CPU') # Checker doesn't support SMT right now
-
-if 'OzoneCPU' in env['CPU_MODELS']:
- need_bp_unit = True
- sources += Split('''
- ozone/base_dyn_inst.cc
- ozone/bpred_unit.cc
- ozone/cpu.cc
- ozone/cpu_builder.cc
- ozone/dyn_inst.cc
- ozone/front_end.cc
- ozone/lw_back_end.cc
- ozone/lw_lsq.cc
- ozone/rename_table.cc
- ''')
- if env['USE_CHECKER']:
- sources += Split('ozone/checker_builder.cc')
-
-if need_bp_unit:
- sources += Split('''
- o3/2bit_local_pred.cc
- o3/btb.cc
- o3/ras.cc
- o3/tournament_pred.cc
- ''')
+Source('activity.cc')
+Source('base.cc')
+Source('cpuevent.cc')
+Source('exetrace.cc')
+Source('func_unit.cc')
+Source('op_class.cc')
+Source('pc_event.cc')
+Source('quiesce_event.cc')
+Source('static_inst.cc')
+Source('simple_thread.cc')
+Source('thread_state.cc')
+
+if env['FULL_SYSTEM']:
+ Source('intr_control.cc')
+ Source('profile.cc')
if env['USE_CHECKER']:
- sources += Split('checker/cpu.cc')
+ Source('checker/cpu.cc')
checker_supports = False
for i in CheckerSupportedCPUList:
if i in env['CPU_MODELS']:
@@ -198,16 +129,5 @@ if env['USE_CHECKER']:
print "Checker only supports CPU models",
for i in CheckerSupportedCPUList:
print i,
- print ", please set USE_CHECKER=False or use one of those CPU models"
+ print ", please set USE_CHECKER=False or use one of those CPU models"
Exit(1)
-
-
-# FullCPU sources are included from src/SConscript since they're not
-# below this point in the file hierarchy.
-
-# Convert file names to SCons File objects. This takes care of the
-# path relative to the top of the directory tree.
-sources = [File(s) for s in sources]
-
-Return('sources')
-
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 03110630c..4dccee0d3 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -63,7 +63,7 @@ int maxThreadsPerCPU = 1;
CPUProgressEvent::CPUProgressEvent(EventQueue *q, Tick ival,
BaseCPU *_cpu)
- : Event(q, Event::Stat_Event_Pri), interval(ival),
+ : Event(q, Event::Progress_Event_Pri), interval(ival),
lastNumInst(0), cpu(_cpu)
{
if (interval)
@@ -320,7 +320,7 @@ BaseCPU::switchOut()
}
void
-BaseCPU::takeOverFrom(BaseCPU *oldCPU)
+BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc)
{
assert(threadContexts.size() == oldCPU->threadContexts.size());
@@ -353,6 +353,26 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
// if (profileEvent)
// profileEvent->schedule(curTick);
#endif
+
+ // Connect new CPU to old CPU's memory only if new CPU isn't
+ // connected to anything. Also connect old CPU's memory to new
+ // CPU.
+ Port *peer;
+ if (ic->getPeer() == NULL) {
+ peer = oldCPU->getPort("icache_port")->getPeer();
+ ic->setPeer(peer);
+ } else {
+ peer = ic->getPeer();
+ }
+ peer->setPeer(ic);
+
+ if (dc->getPeer() == NULL) {
+ peer = oldCPU->getPort("dcache_port")->getPeer();
+ dc->setPeer(peer);
+ } else {
+ peer = dc->getPeer();
+ }
+ peer->setPeer(dc);
}
@@ -373,12 +393,6 @@ BaseCPU::ProfileEvent::process()
}
void
-BaseCPU::post_interrupt(int int_type)
-{
- interrupts.post(int_type);
-}
-
-void
BaseCPU::post_interrupt(int int_num, int index)
{
interrupts.post(int_num, index);
@@ -396,6 +410,11 @@ BaseCPU::clear_interrupts()
interrupts.clear_all();
}
+uint64_t
+BaseCPU::get_interrupts(int int_num)
+{
+ return interrupts.get_vec(int_num);
+}
void
BaseCPU::serialize(std::ostream &os)
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index a1265b748..4d8300186 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -34,11 +34,11 @@
#include <vector>
+#include "arch/isa_traits.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
#include "sim/eventq.hh"
#include "mem/mem_object.hh"
-#include "arch/isa_traits.hh"
#if FULL_SYSTEM
#include "arch/interrupts.hh"
@@ -50,6 +50,11 @@ class ThreadContext;
class System;
class Port;
+namespace TheISA
+{
+ class Predecoder;
+}
+
class CPUProgressEvent : public Event
{
protected:
@@ -102,10 +107,10 @@ class BaseCPU : public MemObject
TheISA::Interrupts interrupts;
public:
- virtual void post_interrupt(int int_type);
virtual void post_interrupt(int int_num, int index);
virtual void clear_interrupt(int int_num, int index);
virtual void clear_interrupts();
+ virtual uint64_t get_interrupts(int int_num);
bool check_interrupts(ThreadContext * tc) const
{ return interrupts.check_interrupts(tc); }
@@ -125,6 +130,7 @@ class BaseCPU : public MemObject
protected:
std::vector<ThreadContext *> threadContexts;
+ std::vector<TheISA::Predecoder *> predecoders;
public:
@@ -196,7 +202,7 @@ class BaseCPU : public MemObject
/// Take over execution from the given CPU. Used for warm-up and
/// sampling.
- virtual void takeOverFrom(BaseCPU *);
+ virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);
/**
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index d6cd9409b..a6af98d66 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -244,7 +244,7 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
!(unverifiedReq->isUncacheable()) &&
(!(unverifiedReq->isLocked()) ||
((unverifiedReq->isLocked()) &&
- unverifiedReq->getScResult() == 1))) {
+ unverifiedReq->getExtraData() == 1))) {
T inst_data;
/*
// This code would work if the LSQ allowed for snooping.
@@ -269,7 +269,7 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// doesn't check if the SC should succeed or fail, it just checks the
// value.
if (res && unverifiedReq->scResultValid())
- *res = unverifiedReq->getScResult();
+ *res = unverifiedReq->getExtraData();
return NoFault;
}
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 3e08193ee..7b3628986 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -298,27 +298,27 @@ class CheckerCPU : public BaseCPU
thread->setNextPC(val);
}
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return thread->readMiscReg(misc_reg);
+ return thread->readMiscRegNoEffect(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return thread->readMiscRegWithEffect(misc_reg);
+ return thread->readMiscReg(misc_reg);
}
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
result.integer = val;
miscRegIdxs.push(misc_reg);
- return thread->setMiscReg(misc_reg, val);
+ return thread->setMiscRegNoEffect(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
miscRegIdxs.push(misc_reg);
- return thread->setMiscRegWithEffect(misc_reg, val);
+ return thread->setMiscReg(misc_reg, val);
}
void recordPCChange(uint64_t val) { changedPC = true; newPC = val; }
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 56e13dd1e..f3f8a0bb3 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -386,13 +386,13 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
int misc_reg_idx = miscRegIdxs.front();
miscRegIdxs.pop();
- if (inst->tcBase()->readMiscReg(misc_reg_idx) !=
- thread->readMiscReg(misc_reg_idx)) {
+ if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
+ thread->readMiscRegNoEffect(misc_reg_idx)) {
warn("%lli: Misc reg idx %i (side effect) does not match! "
"Inst: %#x, checker: %#x",
curTick, misc_reg_idx,
- inst->tcBase()->readMiscReg(misc_reg_idx),
- thread->readMiscReg(misc_reg_idx));
+ inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
+ thread->readMiscRegNoEffect(misc_reg_idx));
handleError(inst);
}
}
@@ -432,7 +432,7 @@ Checker<DynInstPtr>::copyResult(DynInstPtr &inst)
} else if (idx < TheISA::Fpcr_DepTag) {
thread->setFloatRegBits(idx, inst->readIntResult());
} else {
- thread->setMiscReg(idx, inst->readIntResult());
+ thread->setMiscRegNoEffect(idx, inst->readIntResult());
}
}
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index cf36d8392..3b4d21e13 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -248,11 +248,17 @@ class CheckerThreadContext : public ThreadContext
checkerCPU->recordNextPCChange(val);
}
+ MiscReg readMiscRegNoEffect(int misc_reg)
+ { return actualTC->readMiscRegNoEffect(misc_reg); }
+
MiscReg readMiscReg(int misc_reg)
{ return actualTC->readMiscReg(misc_reg); }
- MiscReg readMiscRegWithEffect(int misc_reg)
- { return actualTC->readMiscRegWithEffect(misc_reg); }
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
+ {
+ checkerTC->setMiscRegNoEffect(misc_reg, val);
+ actualTC->setMiscRegNoEffect(misc_reg, val);
+ }
void setMiscReg(int misc_reg, const MiscReg &val)
{
@@ -260,12 +266,6 @@ class CheckerThreadContext : public ThreadContext
actualTC->setMiscReg(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
- {
- checkerTC->setMiscRegWithEffect(misc_reg, val);
- actualTC->setMiscRegWithEffect(misc_reg, val);
- }
-
unsigned readStCondFailures()
{ return actualTC->readStCondFailures(); }
diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh
index edccd747f..2b9fe4bcf 100644
--- a/src/cpu/exec_context.hh
+++ b/src/cpu/exec_context.hh
@@ -100,18 +100,18 @@ class ExecContext {
void setNextNPC(uint64_t val);
/** Reads a miscellaneous register. */
- MiscReg readMiscReg(int misc_reg);
+ MiscReg readMiscRegNoEffect(int misc_reg);
/** Reads a miscellaneous register, handling any architectural
* side effects due to reading that register. */
- MiscReg readMiscRegWithEffect(int misc_reg);
+ MiscReg readMiscReg(int misc_reg);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const MiscReg &val);
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
/** Sets a miscellaneous register, handling any architectural
* side effects due to writing that register. */
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
+ void setMiscReg(int misc_reg, const MiscReg &val);
/** Records the effective address of the instruction. Only valid
* for memory ops. */
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index 5108d7338..c568b1439 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -31,14 +31,17 @@
* Steve Raasch
*/
+#include <errno.h>
#include <fstream>
#include <iomanip>
#include <sys/ipc.h>
#include <sys/shm.h>
+#include "arch/predecoder.hh"
#include "arch/regfile.hh"
#include "arch/utility.hh"
#include "base/loader/symtab.hh"
+#include "base/socket.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
@@ -64,6 +67,28 @@ static bool wasMicro = false;
namespace Trace {
SharedData *shared_data = NULL;
+ListenSocket *cosim_listener = NULL;
+
+void
+setupSharedData()
+{
+ int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
+ if (shmfd < 0)
+ fatal("Couldn't get shared memory fd. Is Legion running?");
+
+ shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
+ if (shared_data == (SharedData*)-1)
+ fatal("Couldn't allocate shared memory");
+
+ if (shared_data->flags != OWN_M5)
+ fatal("Shared memory has invalid owner");
+
+ if (shared_data->version != VERSION)
+ fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
+ shared_data->version);
+
+ // step legion forward one cycle so we can get register values
+ shared_data->flags = OWN_LEGION;
}
////////////////////////////////////////////////////////////////////////
@@ -123,12 +148,101 @@ inline void printLevelHeader(ostream & os, int level)
#endif
void
-Trace::InstRecord::dump(ostream &outs)
+Trace::InstRecord::dump()
{
+ ostream &outs = Trace::output();
+
DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst);
- if (flags[PRINT_REG_DELTA])
+ bool diff = true;
+ if (IsOn(ExecRegDelta))
{
+ diff = false;
+#ifndef NDEBUG
#if THE_ISA == SPARC_ISA
+ static int fd = 0;
+ //Don't print what happens for each micro-op, just print out
+ //once at the last op, and for regular instructions.
+ if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
+ {
+ if(!cosim_listener)
+ {
+ int port = 8000;
+ cosim_listener = new ListenSocket();
+ while(!cosim_listener->listen(port, true))
+ {
+ DPRINTF(GDBMisc, "Can't bind port %d\n", port);
+ port++;
+ }
+ ccprintf(cerr, "Listening for cosimulator on port %d\n", port);
+ fd = cosim_listener->accept();
+ }
+ char prefix[] = "goli";
+ for(int p = 0; p < 4; p++)
+ {
+ for(int i = 0; i < 8; i++)
+ {
+ uint64_t regVal;
+ int res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ uint64_t realRegVal = thread->readIntReg(p * 8 + i);
+ if((regVal & 0xffffffffULL) != (realRegVal & 0xffffffffULL))
+ {
+ DPRINTF(ExecRegDelta, "Register %s%d should be %#x but is %#x.\n", prefix[p], i, regVal, realRegVal);
+ diff = true;
+ }
+ //ccprintf(outs, "%s%d m5 = %#x statetrace = %#x\n", prefix[p], i, realRegVal, regVal);
+ }
+ }
+ /*for(int f = 0; f <= 62; f+=2)
+ {
+ uint64_t regVal;
+ int res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ uint64_t realRegVal = thread->readFloatRegBits(f, 64);
+ if(regVal != realRegVal)
+ {
+ DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
+ }
+ }*/
+ uint64_t regVal;
+ int res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ uint64_t realRegVal = thread->readNextPC();
+ if(regVal != realRegVal)
+ {
+ DPRINTF(ExecRegDelta, "Register pc should be %#x but is %#x.\n", regVal, realRegVal);
+ diff = true;
+ }
+ res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ realRegVal = thread->readNextNPC();
+ if(regVal != realRegVal)
+ {
+ DPRINTF(ExecRegDelta, "Register npc should be %#x but is %#x.\n", regVal, realRegVal);
+ diff = true;
+ }
+ res = read(fd, &regVal, sizeof(regVal));
+ if(res < 0)
+ panic("First read call failed! %s\n", strerror(errno));
+ regVal = TheISA::gtoh(regVal);
+ realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
+ if((regVal & 0xF) != (realRegVal & 0xF))
+ {
+ DPRINTF(ExecRegDelta, "Register ccr should be %#x but is %#x.\n", regVal, realRegVal);
+ diff = true;
+ }
+ }
+#endif
+#endif
+#if 0 //THE_ISA == SPARC_ISA
//Don't print what happens for each micro-op, just print out
//once at the last op, and for regular instructions.
if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
@@ -148,14 +262,14 @@ Trace::InstRecord::dump(ostream &outs)
outs << "PC = " << thread->readNextPC();
outs << " NPC = " << thread->readNextNPC();
newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
- //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
+ //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_CCR);
if(newVal != ccr)
{
outs << " CCR = " << newVal;
ccr = newVal;
}
newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1);
- //newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
+ //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_Y);
if(newVal != y)
{
outs << " Y = " << newVal;
@@ -187,34 +301,26 @@ Trace::InstRecord::dump(ostream &outs)
}
#endif
}
- else if (flags[INTEL_FORMAT]) {
-#if FULL_SYSTEM
- bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system);
-#else
- bool is_trace_system = true;
-#endif
- if (is_trace_system) {
- ccprintf(outs, "%7d ) ", cycle);
- outs << "0x" << hex << PC << ":\t";
- if (staticInst->isLoad()) {
- outs << "<RD 0x" << hex << addr;
- outs << ">";
- } else if (staticInst->isStore()) {
- outs << "<WR 0x" << hex << addr;
- outs << ">";
- }
- outs << endl;
+ if(!diff) {
+ } else if (IsOn(ExecIntel)) {
+ ccprintf(outs, "%7d ) ", when);
+ outs << "0x" << hex << PC << ":\t";
+ if (staticInst->isLoad()) {
+ ccprintf(outs, "<RD %#x>", addr);
+ } else if (staticInst->isStore()) {
+ ccprintf(outs, "<WR %#x>", addr);
}
+ outs << endl;
} else {
- if (flags[PRINT_CYCLE])
- ccprintf(outs, "%7d: ", cycle);
+ if (IsOn(ExecTicks))
+ ccprintf(outs, "%7d: ", when);
outs << thread->getCpuPtr()->name() << " ";
- if (flags[TRACE_MISSPEC])
+ if (IsOn(ExecSpeculative))
outs << (misspeculating ? "-" : "+") << " ";
- if (flags[PRINT_THREAD_NUM])
+ if (IsOn(ExecThread))
outs << "T" << thread->getThreadNum() << " : ";
@@ -222,7 +328,7 @@ Trace::InstRecord::dump(ostream &outs)
Addr sym_addr;
if (debugSymbolTable
&& debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)
- && flags[PC_SYMBOL]) {
+ && IsOn(ExecSymbol)) {
if (PC != sym_addr)
sym_str += csprintf("+%d", PC - sym_addr);
outs << "@" << sym_str << " : ";
@@ -248,11 +354,11 @@ Trace::InstRecord::dump(ostream &outs)
outs << " : ";
- if (flags[PRINT_OP_CLASS]) {
+ if (IsOn(ExecOpClass)) {
outs << opClassStrings[staticInst->opClass()] << " : ";
}
- if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
+ if (IsOn(ExecResult) && data_status != DataInvalid) {
outs << " D=";
#if 0
if (data_status == DataDouble)
@@ -264,10 +370,10 @@ Trace::InstRecord::dump(ostream &outs)
#endif
}
- if (flags[PRINT_EFF_ADDR] && addr_valid)
+ if (IsOn(ExecEffAddr) && addr_valid)
outs << " A=0x" << hex << addr;
- if (flags[PRINT_INT_REGS] && regs_valid) {
+ if (IsOn(ExecIntRegs) && regs_valid) {
for (int i = 0; i < TheISA::NumIntRegs;)
for (int j = i + 1; i <= j; i++)
ccprintf(outs, "r%02d = %#018x%s", i,
@@ -276,10 +382,10 @@ Trace::InstRecord::dump(ostream &outs)
outs << "\n";
}
- if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
+ if (IsOn(ExecFetchSeq) && fetch_seq_valid)
outs << " FetchSeq=" << dec << fetch_seq;
- if (flags[PRINT_CP_SEQ] && cp_seq_valid)
+ if (IsOn(ExecCPSeq) && cp_seq_valid)
outs << " CPSeq=" << dec << cp_seq;
//
@@ -288,8 +394,9 @@ Trace::InstRecord::dump(ostream &outs)
outs << endl;
}
#if THE_ISA == SPARC_ISA && FULL_SYSTEM
+ static TheISA::Predecoder predecoder(NULL);
// Compare
- if (flags[LEGION_LOCKSTEP])
+ if (IsOn(ExecLegion))
{
bool compared = false;
bool diffPC = false;
@@ -321,10 +428,13 @@ Trace::InstRecord::dump(ostream &outs)
bool diffTlb = false;
Addr m5Pc, lgnPc;
+ if (!shared_data)
+ setupSharedData();
+
// We took a trap on a micro-op...
if (wasMicro && !staticInst->isMicroOp())
{
- // let's skip comparing this cycle
+ // let's skip comparing this tick
while (!compared)
if (shared_data->flags == OWN_M5) {
shared_data->flags = OWN_LEGION;
@@ -370,30 +480,30 @@ Trace::InstRecord::dump(ostream &outs)
diffFpRegs = true;
}
}
- uint64_t oldTl = thread->readMiscReg(MISCREG_TL);
+ uint64_t oldTl = thread->readMiscRegNoEffect(MISCREG_TL);
if (oldTl != shared_data->tl)
diffTl = true;
for (int i = 1; i <= MaxTL; i++) {
- thread->setMiscReg(MISCREG_TL, i);
- if (thread->readMiscReg(MISCREG_TPC) !=
+ thread->setMiscRegNoEffect(MISCREG_TL, i);
+ if (thread->readMiscRegNoEffect(MISCREG_TPC) !=
shared_data->tpc[i-1])
diffTpc = true;
- if (thread->readMiscReg(MISCREG_TNPC) !=
+ if (thread->readMiscRegNoEffect(MISCREG_TNPC) !=
shared_data->tnpc[i-1])
diffTnpc = true;
- if (thread->readMiscReg(MISCREG_TSTATE) !=
+ if (thread->readMiscRegNoEffect(MISCREG_TSTATE) !=
shared_data->tstate[i-1])
diffTstate = true;
- if (thread->readMiscReg(MISCREG_TT) !=
+ if (thread->readMiscRegNoEffect(MISCREG_TT) !=
shared_data->tt[i-1])
diffTt = true;
- if (thread->readMiscReg(MISCREG_HTSTATE) !=
+ if (thread->readMiscRegNoEffect(MISCREG_HTSTATE) !=
shared_data->htstate[i-1])
diffHtstate = true;
}
- thread->setMiscReg(MISCREG_TL, oldTl);
+ thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
- if(shared_data->tba != thread->readMiscReg(MISCREG_TBA))
+ if(shared_data->tba != thread->readMiscRegNoEffect(MISCREG_TBA))
diffTba = true;
//When the hpstate register is read by an instruction,
//legion has bit 11 set. When it's in storage, it doesn't.
@@ -401,50 +511,50 @@ Trace::InstRecord::dump(ostream &outs)
//of the registers like that, the bit is always set to 1 and
//we just don't compare it. It's not supposed to matter
//anyway.
- if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE))
+ if((shared_data->hpstate | (1 << 11)) != thread->readMiscRegNoEffect(MISCREG_HPSTATE))
diffHpstate = true;
- if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
+ if(shared_data->htba != thread->readMiscRegNoEffect(MISCREG_HTBA))
diffHtba = true;
- if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
+ if(shared_data->pstate != thread->readMiscRegNoEffect(MISCREG_PSTATE))
diffPstate = true;
- //if(shared_data->y != thread->readMiscReg(MISCREG_Y))
+ //if(shared_data->y != thread->readMiscRegNoEffect(MISCREG_Y))
if(shared_data->y !=
thread->readIntReg(NumIntArchRegs + 1))
diffY = true;
- if(shared_data->fsr != thread->readMiscReg(MISCREG_FSR)) {
+ if(shared_data->fsr != thread->readMiscRegNoEffect(MISCREG_FSR)) {
diffFsr = true;
if (mbits(shared_data->fsr, 63,10) ==
- mbits(thread->readMiscReg(MISCREG_FSR), 63,10)) {
- thread->setMiscReg(MISCREG_FSR, shared_data->fsr);
+ mbits(thread->readMiscRegNoEffect(MISCREG_FSR), 63,10)) {
+ thread->setMiscRegNoEffect(MISCREG_FSR, shared_data->fsr);
diffFsr = false;
}
}
- //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
+ //if(shared_data->ccr != thread->readMiscRegNoEffect(MISCREG_CCR))
if(shared_data->ccr !=
thread->readIntReg(NumIntArchRegs + 2))
diffCcr = true;
- if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
+ if(shared_data->gl != thread->readMiscRegNoEffect(MISCREG_GL))
diffGl = true;
- if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
+ if(shared_data->asi != thread->readMiscRegNoEffect(MISCREG_ASI))
diffAsi = true;
- if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
+ if(shared_data->pil != thread->readMiscRegNoEffect(MISCREG_PIL))
diffPil = true;
- if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
+ if(shared_data->cwp != thread->readMiscRegNoEffect(MISCREG_CWP))
diffCwp = true;
- //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
+ //if(shared_data->cansave != thread->readMiscRegNoEffect(MISCREG_CANSAVE))
if(shared_data->cansave !=
thread->readIntReg(NumIntArchRegs + 3))
diffCansave = true;
//if(shared_data->canrestore !=
- // thread->readMiscReg(MISCREG_CANRESTORE))
+ // thread->readMiscRegNoEffect(MISCREG_CANRESTORE))
if(shared_data->canrestore !=
thread->readIntReg(NumIntArchRegs + 4))
diffCanrestore = true;
- //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
+ //if(shared_data->otherwin != thread->readMiscRegNoEffect(MISCREG_OTHERWIN))
if(shared_data->otherwin !=
thread->readIntReg(NumIntArchRegs + 6))
diffOtherwin = true;
- //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
+ //if(shared_data->cleanwin != thread->readMiscRegNoEffect(MISCREG_CLEANWIN))
if(shared_data->cleanwin !=
thread->readIntReg(NumIntArchRegs + 5))
diffCleanwin = true;
@@ -539,9 +649,13 @@ Trace::InstRecord::dump(ostream &outs)
<< staticInst->disassemble(m5Pc, debugSymbolTable)
<< endl;
+ predecoder.setTC(thread);
+ predecoder.moreBytes(m5Pc, 0, shared_data->instruction);
+
+ assert(predecoder.extMachInstRead());
+
StaticInstPtr legionInst =
- StaticInst::decode(makeExtMI(shared_data->instruction,
- thread));
+ StaticInst::decode(predecoder.getExtMachInst());
outs << setfill(' ') << setw(15)
<< " Legion Inst: "
<< "0x" << setw(8) << setfill('0') << hex
@@ -552,78 +666,78 @@ Trace::InstRecord::dump(ostream &outs)
printSectionHeader(outs, "General State");
printColumnLabels(outs);
printRegPair(outs, "HPstate",
- thread->readMiscReg(MISCREG_HPSTATE),
+ thread->readMiscRegNoEffect(MISCREG_HPSTATE),
shared_data->hpstate | (1 << 11));
printRegPair(outs, "Htba",
- thread->readMiscReg(MISCREG_HTBA),
+ thread->readMiscRegNoEffect(MISCREG_HTBA),
shared_data->htba);
printRegPair(outs, "Pstate",
- thread->readMiscReg(MISCREG_PSTATE),
+ thread->readMiscRegNoEffect(MISCREG_PSTATE),
shared_data->pstate);
printRegPair(outs, "Y",
- //thread->readMiscReg(MISCREG_Y),
+ //thread->readMiscRegNoEffect(MISCREG_Y),
thread->readIntReg(NumIntArchRegs + 1),
shared_data->y);
printRegPair(outs, "FSR",
- thread->readMiscReg(MISCREG_FSR),
+ thread->readMiscRegNoEffect(MISCREG_FSR),
shared_data->fsr);
printRegPair(outs, "Ccr",
- //thread->readMiscReg(MISCREG_CCR),
+ //thread->readMiscRegNoEffect(MISCREG_CCR),
thread->readIntReg(NumIntArchRegs + 2),
shared_data->ccr);
printRegPair(outs, "Tl",
- thread->readMiscReg(MISCREG_TL),
+ thread->readMiscRegNoEffect(MISCREG_TL),
shared_data->tl);
printRegPair(outs, "Gl",
- thread->readMiscReg(MISCREG_GL),
+ thread->readMiscRegNoEffect(MISCREG_GL),
shared_data->gl);
printRegPair(outs, "Asi",
- thread->readMiscReg(MISCREG_ASI),
+ thread->readMiscRegNoEffect(MISCREG_ASI),
shared_data->asi);
printRegPair(outs, "Pil",
- thread->readMiscReg(MISCREG_PIL),
+ thread->readMiscRegNoEffect(MISCREG_PIL),
shared_data->pil);
printRegPair(outs, "Cwp",
- thread->readMiscReg(MISCREG_CWP),
+ thread->readMiscRegNoEffect(MISCREG_CWP),
shared_data->cwp);
printRegPair(outs, "Cansave",
- //thread->readMiscReg(MISCREG_CANSAVE),
+ //thread->readMiscRegNoEffect(MISCREG_CANSAVE),
thread->readIntReg(NumIntArchRegs + 3),
shared_data->cansave);
printRegPair(outs, "Canrestore",
- //thread->readMiscReg(MISCREG_CANRESTORE),
+ //thread->readMiscRegNoEffect(MISCREG_CANRESTORE),
thread->readIntReg(NumIntArchRegs + 4),
shared_data->canrestore);
printRegPair(outs, "Otherwin",
- //thread->readMiscReg(MISCREG_OTHERWIN),
+ //thread->readMiscRegNoEffect(MISCREG_OTHERWIN),
thread->readIntReg(NumIntArchRegs + 6),
shared_data->otherwin);
printRegPair(outs, "Cleanwin",
- //thread->readMiscReg(MISCREG_CLEANWIN),
+ //thread->readMiscRegNoEffect(MISCREG_CLEANWIN),
thread->readIntReg(NumIntArchRegs + 5),
shared_data->cleanwin);
outs << endl;
for (int i = 1; i <= MaxTL; i++) {
printLevelHeader(outs, i);
printColumnLabels(outs);
- thread->setMiscReg(MISCREG_TL, i);
+ thread->setMiscRegNoEffect(MISCREG_TL, i);
printRegPair(outs, "Tpc",
- thread->readMiscReg(MISCREG_TPC),
+ thread->readMiscRegNoEffect(MISCREG_TPC),
shared_data->tpc[i-1]);
printRegPair(outs, "Tnpc",
- thread->readMiscReg(MISCREG_TNPC),
+ thread->readMiscRegNoEffect(MISCREG_TNPC),
shared_data->tnpc[i-1]);
printRegPair(outs, "Tstate",
- thread->readMiscReg(MISCREG_TSTATE),
+ thread->readMiscRegNoEffect(MISCREG_TSTATE),
shared_data->tstate[i-1]);
printRegPair(outs, "Tt",
- thread->readMiscReg(MISCREG_TT),
+ thread->readMiscRegNoEffect(MISCREG_TT),
shared_data->tt[i-1]);
printRegPair(outs, "Htstate",
- thread->readMiscReg(MISCREG_HTSTATE),
+ thread->readMiscRegNoEffect(MISCREG_HTSTATE),
shared_data->htstate[i-1]);
}
- thread->setMiscReg(MISCREG_TL, oldTl);
+ thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
outs << endl;
printSectionHeader(outs, "General Purpose Registers");
@@ -684,110 +798,4 @@ Trace::InstRecord::dump(ostream &outs)
#endif
}
-
-vector<bool> Trace::InstRecord::flags(NUM_BITS);
-string Trace::InstRecord::trace_system;
-
-////////////////////////////////////////////////////////////////////////
-//
-// Parameter space for per-cycle execution address tracing options.
-// Derive from ParamContext so we can override checkParams() function.
-//
-class ExecutionTraceParamContext : public ParamContext
-{
- public:
- ExecutionTraceParamContext(const string &_iniSection)
- : ParamContext(_iniSection)
- {
- }
-
- void checkParams(); // defined at bottom of file
-};
-
-ExecutionTraceParamContext exeTraceParams("exetrace");
-
-Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
- "capture speculative instructions", true);
-
-Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
- "print cycle number", true);
-Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
- "print op class", true);
-Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
- "print thread number", true);
-Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
- "print effective address", true);
-Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
- "print result data", true);
-Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
- "print all integer regs", false);
-Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
- "print fetch sequence number", false);
-Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
- "print correct-path sequence number", false);
-Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
- "print which registers changed to what", false);
-Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
- "Use symbols for the PC if available", true);
-Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
- "print trace in intel compatible format", false);
-Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
- "Compare sim state to legion state every cycle",
- false);
-Param<string> exe_trace_system(&exeTraceParams, "trace_system",
- "print trace of which system (client or server)",
- "client");
-
-
-//
-// Helper function for ExecutionTraceParamContext::checkParams() just
-// to get us into the InstRecord namespace
-//
-void
-Trace::InstRecord::setParams()
-{
- flags[TRACE_MISSPEC] = exe_trace_spec;
-
- flags[PRINT_CYCLE] = exe_trace_print_cycle;
- flags[PRINT_OP_CLASS] = exe_trace_print_opclass;
- flags[PRINT_THREAD_NUM] = exe_trace_print_thread;
- flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
- flags[PRINT_EFF_ADDR] = exe_trace_print_data;
- flags[PRINT_INT_REGS] = exe_trace_print_iregs;
- flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq;
- flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq;
- flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta;
- flags[PC_SYMBOL] = exe_trace_pc_symbol;
- flags[INTEL_FORMAT] = exe_trace_intel_format;
- flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep;
- trace_system = exe_trace_system;
-
- // If were going to be in lockstep with Legion
- // Setup shared memory, and get otherwise ready
- if (flags[LEGION_LOCKSTEP]) {
- int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
- if (shmfd < 0)
- fatal("Couldn't get shared memory fd. Is Legion running?");
-
- shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
- if (shared_data == (SharedData*)-1)
- fatal("Couldn't allocate shared memory");
-
- if (shared_data->flags != OWN_M5)
- fatal("Shared memory has invalid owner");
-
- if (shared_data->version != VERSION)
- fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
- shared_data->version);
-
- // step legion forward one cycle so we can get register values
- shared_data->flags = OWN_LEGION;
- }
-}
-
-void
-ExecutionTraceParamContext::checkParams()
-{
- Trace::InstRecord::setParams();
-}
-
+/* namespace Trace */ }
diff --git a/src/cpu/exetrace.hh b/src/cpu/exetrace.hh
index a825f6a82..8c0fa22cb 100644
--- a/src/cpu/exetrace.hh
+++ b/src/cpu/exetrace.hh
@@ -36,22 +36,24 @@
#include <fstream>
#include <vector>
-#include "sim/host.hh"
-#include "cpu/inst_seq.hh" // for InstSeqNum
#include "base/trace.hh"
-#include "cpu/thread_context.hh"
+#include "cpu/inst_seq.hh" // for InstSeqNum
#include "cpu/static_inst.hh"
+#include "cpu/thread_context.hh"
+#include "sim/host.hh"
class ThreadContext;
namespace Trace {
-class InstRecord : public Record
+class InstRecord
{
protected:
typedef TheISA::IntRegFile IntRegFile;
+ Tick when;
+
// The following fields are initialized by the constructor and
// thus guaranteed to be valid.
ThreadContext *thread;
@@ -95,10 +97,10 @@ class InstRecord : public Record
bool regs_valid;
public:
- InstRecord(Tick _cycle, ThreadContext *_thread,
+ InstRecord(Tick _when, ThreadContext *_thread,
const StaticInstPtr &_staticInst,
Addr _pc, bool spec)
- : Record(_cycle), thread(_thread),
+ : when(_when), thread(_thread),
staticInst(_staticInst), PC(_pc),
misspeculating(spec)
{
@@ -110,12 +112,12 @@ class InstRecord : public Record
cp_seq_valid = false;
}
- virtual ~InstRecord() { }
-
- virtual void dump(std::ostream &outs);
+ ~InstRecord() { }
void setAddr(Addr a) { addr = a; addr_valid = true; }
+ void setData(Twin64_t d) { data.as_int = d.a; data_status = DataInt64; }
+ void setData(Twin32_t d) { data.as_int = d.a; data_status = DataInt32; }
void setData(uint64_t d) { data.as_int = d; data_status = DataInt64; }
void setData(uint32_t d) { data.as_int = d; data_status = DataInt32; }
void setData(uint16_t d) { data.as_int = d; data_status = DataInt16; }
@@ -136,31 +138,7 @@ class InstRecord : public Record
void setRegs(const IntRegFile &regs);
- void finalize() { theLog.append(this); }
-
- enum InstExecFlagBits {
- TRACE_MISSPEC = 0,
- PRINT_CYCLE,
- PRINT_OP_CLASS,
- PRINT_THREAD_NUM,
- PRINT_RESULT_DATA,
- PRINT_EFF_ADDR,
- PRINT_INT_REGS,
- PRINT_FETCH_SEQ,
- PRINT_CP_SEQ,
- PRINT_REG_DELTA,
- PC_SYMBOL,
- INTEL_FORMAT,
- LEGION_LOCKSTEP,
- NUM_BITS
- };
-
- static std::vector<bool> flags;
- static std::string trace_system;
-
- static void setParams();
-
- static bool traceMisspec() { return flags[TRACE_MISSPEC]; }
+ void dump();
};
@@ -174,22 +152,22 @@ InstRecord::setRegs(const IntRegFile &regs)
regs_valid = true;
}
-inline
-InstRecord *
-getInstRecord(Tick cycle, ThreadContext *tc,
- const StaticInstPtr staticInst,
+inline InstRecord *
+getInstRecord(Tick when, ThreadContext *tc, const StaticInstPtr staticInst,
Addr pc)
{
- if (DTRACE(InstExec) &&
- (InstRecord::traceMisspec() || !tc->misspeculating())) {
- return new InstRecord(cycle, tc, staticInst, pc,
- tc->misspeculating());
- }
+ if (!IsOn(ExecEnable))
+ return NULL;
- return NULL;
-}
+ if (!Trace::enabled)
+ return NULL;
+ if (!IsOn(ExecSpeculative) && tc->misspeculating())
+ return NULL;
+ return new InstRecord(when, tc, staticInst, pc, tc->misspeculating());
}
+/* namespace Trace */ }
+
#endif // __EXETRACE_HH__
diff --git a/src/cpu/intr_control.cc b/src/cpu/intr_control.cc
index 4cbc86891..be0f6599b 100644
--- a/src/cpu/intr_control.cc
+++ b/src/cpu/intr_control.cc
@@ -40,18 +40,14 @@
using namespace std;
-IntrControl::IntrControl(const string &name, BaseCPU *c)
- : SimObject(name), cpu(c)
+IntrControl::IntrControl(const string &name, System *s)
+ : SimObject(name), sys(s)
{}
-/* @todo
- *Fix the cpu sim object parameter to be a system pointer
- *instead, to avoid some extra dereferencing
- */
void
IntrControl::post(int int_num, int index)
{
- std::vector<ThreadContext *> &tcvec = cpu->system->threadContexts;
+ std::vector<ThreadContext *> &tcvec = sys->threadContexts;
BaseCPU *temp = tcvec[0]->getCpuPtr();
temp->post_interrupt(int_num, index);
}
@@ -59,7 +55,7 @@ IntrControl::post(int int_num, int index)
void
IntrControl::post(int cpu_id, int int_num, int index)
{
- std::vector<ThreadContext *> &tcvec = cpu->system->threadContexts;
+ std::vector<ThreadContext *> &tcvec = sys->threadContexts;
BaseCPU *temp = tcvec[cpu_id]->getCpuPtr();
temp->post_interrupt(int_num, index);
}
@@ -67,7 +63,7 @@ IntrControl::post(int cpu_id, int int_num, int index)
void
IntrControl::clear(int int_num, int index)
{
- std::vector<ThreadContext *> &tcvec = cpu->system->threadContexts;
+ std::vector<ThreadContext *> &tcvec = sys->threadContexts;
BaseCPU *temp = tcvec[0]->getCpuPtr();
temp->clear_interrupt(int_num, index);
}
@@ -75,26 +71,26 @@ IntrControl::clear(int int_num, int index)
void
IntrControl::clear(int cpu_id, int int_num, int index)
{
- std::vector<ThreadContext *> &tcvec = cpu->system->threadContexts;
+ std::vector<ThreadContext *> &tcvec = sys->threadContexts;
BaseCPU *temp = tcvec[cpu_id]->getCpuPtr();
temp->clear_interrupt(int_num, index);
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
- SimObjectParam<BaseCPU *> cpu;
+ SimObjectParam<System *> sys;
END_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
BEGIN_INIT_SIM_OBJECT_PARAMS(IntrControl)
- INIT_PARAM(cpu, "the cpu")
+ INIT_PARAM(sys, "the system we are part of")
END_INIT_SIM_OBJECT_PARAMS(IntrControl)
CREATE_SIM_OBJECT(IntrControl)
{
- return new IntrControl(getInstanceName(), cpu);
+ return new IntrControl(getInstanceName(), sys);
}
REGISTER_SIM_OBJECT("IntrControl", IntrControl)
diff --git a/src/cpu/intr_control.hh b/src/cpu/intr_control.hh
index 2e3f9e038..c6f75abf0 100644
--- a/src/cpu/intr_control.hh
+++ b/src/cpu/intr_control.hh
@@ -42,8 +42,8 @@
class IntrControl : public SimObject
{
public:
- BaseCPU *cpu;
- IntrControl(const std::string &name, BaseCPU *c);
+ System *sys;
+ IntrControl(const std::string &name, System *s);
void clear(int int_num, int index = 0);
void post(int int_num, int index = 0);
diff --git a/src/cpu/memtest/SConscript b/src/cpu/memtest/SConscript
new file mode 100644
index 000000000..7b4d6d2c5
--- /dev/null
+++ b/src/cpu/memtest/SConscript
@@ -0,0 +1,34 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+Import('*')
+
+if 'O3CPU' in env['CPU_MODELS']:
+ Source('memtest.cc')
diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
index 180f41541..607cf1066 100644
--- a/src/cpu/memtest/memtest.cc
+++ b/src/cpu/memtest/memtest.cc
@@ -226,8 +226,8 @@ MemTest::completeRequest(PacketPtr pkt)
assert(removeAddr != outstandingAddrs.end());
outstandingAddrs.erase(removeAddr);
- switch (pkt->cmd) {
- case Packet::ReadResp:
+ switch (pkt->cmd.toInt()) {
+ case MemCmd::ReadResp:
if (memcmp(pkt_data, data, pkt->getSize()) != 0) {
cerr << name() << ": on read of 0x" << hex << req->getPaddr()
@@ -254,7 +254,7 @@ MemTest::completeRequest(PacketPtr pkt)
exitSimLoop("Maximum number of loads reached!");
break;
- case Packet::WriteResp:
+ case MemCmd::WriteResp:
numWritesStat++;
break;
/*
@@ -369,7 +369,7 @@ MemTest::tick()
//This means we assume CPU does write forwarding to reads that alias something
//in the cpu store buffer.
if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) {
- delete result;
+ delete [] result;
delete req;
return;
}
@@ -389,7 +389,7 @@ MemTest::tick()
<< dec << curTick << endl;
}
- PacketPtr pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
pkt->dataDynamicArray(new uint8_t[req->getSize()]);
MemTestSenderState *state = new MemTestSenderState(result);
pkt->senderState = state;
@@ -429,7 +429,7 @@ MemTest::tick()
<< dec << curTick << endl;
}
*/
- PacketPtr pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
uint8_t *pkt_data = new uint8_t[req->getSize()];
pkt->dataDynamicArray(pkt_data);
memcpy(pkt_data, &data, req->getSize());
diff --git a/src/cpu/o3/SConscript b/src/cpu/o3/SConscript
index afbd4c533..bb1dfb613 100755
--- a/src/cpu/o3/SConscript
+++ b/src/cpu/o3/SConscript
@@ -26,52 +26,56 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
-# Authors: Korey Sewell
+# Authors: Nathan Binkert
-import os
-import os.path
import sys
-# Import build environment variable from SConstruct.
-Import('env')
+Import('*')
+if 'O3CPU' in env['CPU_MODELS']:
+ Source('base_dyn_inst.cc')
+ Source('bpred_unit.cc')
+ Source('commit.cc')
+ Source('cpu.cc')
+ Source('decode.cc')
+ Source('fetch.cc')
+ Source('free_list.cc')
+ Source('fu_pool.cc')
+ Source('iew.cc')
+ Source('inst_queue.cc')
+ Source('lsq.cc')
+ Source('lsq_unit.cc')
+ Source('mem_dep_unit.cc')
+ Source('rename.cc')
+ Source('rename_map.cc')
+ Source('rob.cc')
+ Source('scoreboard.cc')
+ Source('store_set.cc')
-#################################################################
-#
-# Include ISA-specific files for the O3 CPU-model
-#
-#################################################################
-
-sources = []
-
-if env['TARGET_ISA'] == 'alpha':
- sources += Split('''
- alpha/dyn_inst.cc
- alpha/cpu.cc
- alpha/thread_context.cc
- alpha/cpu_builder.cc
- ''')
-elif env['TARGET_ISA'] == 'mips':
- sources += Split('''
- mips/dyn_inst.cc
- mips/cpu.cc
- mips/thread_context.cc
- mips/cpu_builder.cc
- ''')
-elif env['TARGET_ISA'] == 'sparc':
- sources += Split('''
- sparc/dyn_inst.cc
- sparc/cpu.cc
- sparc/thread_context.cc
- sparc/cpu_builder.cc
- ''')
-else:
- sys.exit('O3 CPU does not support the \'%s\' ISA' % env['TARGET_ISA'])
-
+ if env['TARGET_ISA'] == 'alpha':
+ Source('alpha/cpu.cc')
+ Source('alpha/cpu_builder.cc')
+ Source('alpha/dyn_inst.cc')
+ Source('alpha/thread_context.cc')
+ elif env['TARGET_ISA'] == 'mips':
+ Source('mips/cpu.cc')
+ Source('mips/cpu_builder.cc')
+ Source('mips/dyn_inst.cc')
+ Source('mips/thread_context.cc')
+ elif env['TARGET_ISA'] == 'sparc':
+ Source('sparc/cpu.cc')
+ Source('sparc/cpu_builder.cc')
+ Source('sparc/dyn_inst.cc')
+ Source('sparc/thread_context.cc')
+ else:
+ sys.exit('O3 CPU does not support the \'%s\' ISA' % env['TARGET_ISA'])
-# Convert file names to SCons File objects. This takes care of the
-# path relative to the top of the directory tree.
-sources = [File(s) for s in sources]
+ if env['USE_CHECKER']:
+ Source('checker_builder.cc')
-Return('sources')
+if 'O3CPU' in env['CPU_MODELS'] or 'OzoneCPU' in env['CPU_MODELS']:
+ Source('2bit_local_pred.cc')
+ Source('btb.cc')
+ Source('ras.cc')
+ Source('tournament_pred.cc')
diff --git a/src/cpu/o3/SConsopts b/src/cpu/o3/SConsopts
new file mode 100644
index 000000000..040352e6a
--- /dev/null
+++ b/src/cpu/o3/SConsopts
@@ -0,0 +1,34 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+Import('*')
+
+all_cpu_list.append('O3CPU')
+default_cpus.append('O3CPU')
diff --git a/src/cpu/o3/alpha/cpu.hh b/src/cpu/o3/alpha/cpu.hh
index 4a2086296..676893098 100644
--- a/src/cpu/o3/alpha/cpu.hh
+++ b/src/cpu/o3/alpha/cpu.hh
@@ -106,21 +106,21 @@ class AlphaO3CPU : public FullO3CPU<Impl>
#endif
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
+ void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val,
unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val,
+ void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh
index 7799d8f05..304ee6c38 100644
--- a/src/cpu/o3/alpha/cpu_impl.hh
+++ b/src/cpu/o3/alpha/cpu_impl.hh
@@ -155,32 +155,32 @@ AlphaO3CPU<Impl>::regStats()
template <class Impl>
TheISA::MiscReg
-AlphaO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
+AlphaO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscReg(misc_reg, tid);
+ return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
TheISA::MiscReg
-AlphaO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
+AlphaO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscRegWithEffect(misc_reg, tid);
+ return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
-AlphaO3CPU<Impl>::setMiscReg(int misc_reg, const TheISA::MiscReg &val,
+AlphaO3CPU<Impl>::setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val,
unsigned tid)
{
- this->regFile.setMiscReg(misc_reg, val, tid);
+ this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
-AlphaO3CPU<Impl>::setMiscRegWithEffect(int misc_reg,
+AlphaO3CPU<Impl>::setMiscReg(int misc_reg,
const TheISA::MiscReg &val, unsigned tid)
{
- this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
+ this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
@@ -210,7 +210,7 @@ Fault
AlphaO3CPU<Impl>::hwrei(unsigned tid)
{
// Need to clear the lock flag upon returning from an interrupt.
- this->setMiscReg(AlphaISA::MISCREG_LOCKFLAG, false, tid);
+ this->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, false, tid);
this->thread[tid]->kernelStats->hwrei();
diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh
index 603a1b52d..20759d849 100644
--- a/src/cpu/o3/alpha/dyn_inst.hh
+++ b/src/cpu/o3/alpha/dyn_inst.hh
@@ -95,39 +95,39 @@ class AlphaDynInst : public BaseDynInst<Impl>
public:
/** Reads a miscellaneous register. */
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return this->cpu->readMiscReg(misc_reg, this->threadNumber);
+ return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
}
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
+ return this->cpu->readMiscReg(misc_reg, this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
this->instResult.integer = val;
- return this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
+ return this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
}
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(misc_reg, val,
+ return this->cpu->setMiscReg(misc_reg, val,
this->threadNumber);
}
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+ TheISA::MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
{
- return this->cpu->readMiscReg(
+ return this->cpu->readMiscRegNoEffect(
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
this->threadNumber);
}
@@ -135,18 +135,18 @@ class AlphaDynInst : public BaseDynInst<Impl>
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+ TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readMiscRegWithEffect(
+ return this->cpu->readMiscReg(
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscRegOperand(const StaticInst * si, int idx, const MiscReg &val)
+ void setMiscRegOperandNoEffect(const StaticInst * si, int idx, const MiscReg &val)
{
this->instResult.integer = val;
- return this->cpu->setMiscReg(
+ return this->cpu->setMiscRegNoEffect(
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
val, this->threadNumber);
}
@@ -154,10 +154,10 @@ class AlphaDynInst : public BaseDynInst<Impl>
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegOperandWithEffect(const StaticInst *si, int idx,
+ void setMiscRegOperand(const StaticInst *si, int idx,
const MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(
+ return this->cpu->setMiscReg(
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
val, this->threadNumber);
}
diff --git a/src/cpu/o3/alpha/dyn_inst_impl.hh b/src/cpu/o3/alpha/dyn_inst_impl.hh
index 50cdec408..fdce1ade5 100644
--- a/src/cpu/o3/alpha/dyn_inst_impl.hh
+++ b/src/cpu/o3/alpha/dyn_inst_impl.hh
@@ -118,7 +118,7 @@ AlphaDynInst<Impl>::hwrei()
return new AlphaISA::UnimplementedOpcodeFault;
// Set the next PC based on the value of the EXC_ADDR IPR.
- this->setNextPC(this->cpu->readMiscReg(AlphaISA::IPR_EXC_ADDR,
+ this->setNextPC(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
this->threadNumber));
// Tell CPU to clear any state it needs to if a hwrei is taken.
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index b42a6f523..c17c8836d 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -1148,7 +1148,8 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
if (head_inst->traceData) {
head_inst->traceData->setFetchSeq(head_inst->seqNum);
head_inst->traceData->setCPSeq(thread[tid]->numInst);
- head_inst->traceData->finalize();
+ head_inst->traceData->dump();
+ delete head_inst->traceData;
head_inst->traceData = NULL;
}
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index f9e094d75..354e3c490 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -45,7 +45,7 @@
#include "cpu/o3/isa_specific.hh"
#include "cpu/o3/cpu.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "sim/stat_control.hh"
#if USE_CHECKER
@@ -557,12 +557,6 @@ template <class Impl>
void
FullO3CPU<Impl>::activateContext(int tid, int delay)
{
-#if FULL_SYSTEM
- // Connect the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- threadContexts[tid]->connectMemPorts();
-#endif
-
// Needs to set each stage to running as well.
if (delay){
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
@@ -781,6 +775,18 @@ FullO3CPU<Impl>::activateWhenReady(int tid)
}
}
+#if FULL_SYSTEM
+template <class Impl>
+void
+FullO3CPU<Impl>::updateMemPorts()
+{
+ // Update all ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ for (int i = 0; i < thread.size(); ++i)
+ thread[i]->connectMemPorts();
+}
+#endif
+
template <class Impl>
void
FullO3CPU<Impl>::serialize(std::ostream &os)
@@ -941,7 +947,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
activityRec.reset();
- BaseCPU::takeOverFrom(oldCPU);
+ BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort());
fetch.takeOverFrom();
decode.takeOverFrom();
@@ -978,25 +984,6 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
}
if (!tickEvent.scheduled())
tickEvent.schedule(nextCycle());
-
- Port *peer;
- Port *icachePort = fetch.getIcachePort();
- if (icachePort->getPeer() == NULL) {
- peer = oldCPU->getPort("icache_port")->getPeer();
- icachePort->setPeer(peer);
- } else {
- peer = icachePort->getPeer();
- }
- peer->setPeer(icachePort);
-
- Port *dcachePort = iew.getDcachePort();
- if (dcachePort->getPeer() == NULL) {
- peer = oldCPU->getPort("dcache_port")->getPeer();
- dcachePort->setPeer(peer);
- } else {
- peer = dcachePort->getPeer();
- }
- peer->setPeer(dcachePort);
}
template <class Impl>
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index b47c2a494..0ab20ba2a 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -361,6 +361,10 @@ class FullO3CPU : public BaseO3CPU
{ return globalSeqNum++; }
#if FULL_SYSTEM
+ /** Update the Virt and Phys ports of all ThreadContexts to
+ * reflect change in memory connections. */
+ void updateMemPorts();
+
/** Check if this address is a valid instruction address. */
bool validInstAddr(Addr addr) { return true; }
diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh
index 279513493..c37f8007e 100644
--- a/src/cpu/o3/dyn_inst.hh
+++ b/src/cpu/o3/dyn_inst.hh
@@ -45,6 +45,10 @@
template <class Impl> class SparcDynInst;
struct SparcSimpleImpl;
typedef SparcDynInst<SparcSimpleImpl> O3DynInst;
+#elif THE_ISA == X86_ISA
+ template <class Impl> class X86DynInst;
+ struct X86SimpleImpl;
+ typedef X86DynInst<X86SimpleImpl> O3DynInst;
#else
#error "O3DynInst not defined for this ISA"
#endif
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 8347ed775..da7ce00f5 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -33,6 +33,7 @@
#define __CPU_O3_FETCH_HH__
#include "arch/utility.hh"
+#include "arch/predecoder.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/pc_event.hh"
@@ -338,6 +339,9 @@ class DefaultFetch
/** BPredUnit. */
BPredUnit branchPred;
+ /** Predecoder. */
+ TheISA::Predecoder predecoder;
+
/** Per-thread fetch PC. */
Addr PC[Impl::MaxThreads];
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index a8727a425..663cd3142 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -40,7 +40,7 @@
#include "mem/request.hh"
#include "sim/byteswap.hh"
#include "sim/host.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#if FULL_SYSTEM
#include "arch/tlb.hh"
@@ -103,6 +103,7 @@ DefaultFetch<Impl>::IcachePort::recvRetry()
template<class Impl>
DefaultFetch<Impl>::DefaultFetch(Params *params)
: branchPred(params),
+ predecoder(NULL),
decodeToFetchDelay(params->decodeToFetchDelay),
renameToFetchDelay(params->renameToFetchDelay),
iewToFetchDelay(params->iewToFetchDelay),
@@ -602,7 +603,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
// Build packet here.
PacketPtr data_pkt = new Packet(mem_req,
- Packet::ReadReq, Packet::Broadcast);
+ MemCmd::ReadReq, Packet::Broadcast);
data_pkt->dataDynamicArray(new uint8_t[cacheBlkSize]);
cacheDataPC[tid] = block_PC;
@@ -1119,13 +1120,10 @@ DefaultFetch<Impl>::fetch(bool &status_change)
inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
(&cacheData[tid][offset]));
-#if THE_ISA == ALPHA_ISA
- ext_inst = TheISA::makeExtMI(inst, fetch_PC);
-#elif THE_ISA == SPARC_ISA
- ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC());
-#elif THE_ISA == MIPS_ISA
- ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC());
-#endif
+ predecoder.setTC(cpu->thread[tid]->getTC());
+ predecoder.moreBytes(fetch_PC, 0, inst);
+
+ ext_inst = predecoder.getExtMachInst();
// Create a new DynInst from the instruction fetched.
DynInstPtr instruction = new DynInst(ext_inst,
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index 87bf60dfa..79e03d4bf 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -32,7 +32,7 @@
#include <limits>
#include <vector>
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "cpu/o3/fu_pool.hh"
#include "cpu/o3/inst_queue.hh"
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index e68085cfd..80f53a726 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -300,6 +300,8 @@ class LSQ {
bool snoopRangeSent;
+ virtual void setPeer(Port *port);
+
protected:
/** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
@@ -327,6 +329,11 @@ class LSQ {
/** D-cache port. */
DcachePort dcachePort;
+#if FULL_SYSTEM
+ /** Tell the CPU to update the Phys and Virt ports. */
+ void updateMemPorts() { cpu->updateMemPorts(); }
+#endif
+
protected:
/** The LSQ policy for SMT mode. */
LSQPolicy lsqPolicy;
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index fb738f7c9..d4994fcb7 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -34,6 +34,19 @@
#include "cpu/o3/lsq.hh"
+template<class Impl>
+void
+LSQ<Impl>::DcachePort::setPeer(Port *port)
+{
+ Port::setPeer(port);
+
+#if FULL_SYSTEM
+ // Update the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ lsq->updateMemPorts();
+#endif
+}
+
template <class Impl>
Tick
LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index 704d2183d..1b10843f5 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -583,7 +583,8 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
"addr %#x, data %#x\n",
store_idx, req->getVaddr(), data);
- PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr data_pkt = new Packet(req, MemCmd::ReadReq,
+ Packet::Broadcast);
data_pkt->dataStatic(load_inst->memData);
WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this);
@@ -653,7 +654,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
// if we the cache is not blocked, do cache access
if (!lsq->cacheBlocked()) {
PacketPtr data_pkt =
- new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
data_pkt->dataStatic(load_inst->memData);
LSQSenderState *state = new LSQSenderState;
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index ed331386b..e70c960b3 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -656,7 +656,8 @@ LSQUnit<Impl>::writebackStores()
(sizeof(TheISA::IntReg) - req->getSize()) : 0),
req->getSize());
- PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ PacketPtr data_pkt = new Packet(req, MemCmd::WriteReq,
+ Packet::Broadcast);
data_pkt->dataStatic(inst->memData);
LSQSenderState *state = new LSQSenderState;
diff --git a/src/cpu/o3/mips/cpu.hh b/src/cpu/o3/mips/cpu.hh
index 7e6268cdf..0361c1814 100755
--- a/src/cpu/o3/mips/cpu.hh
+++ b/src/cpu/o3/mips/cpu.hh
@@ -87,20 +87,20 @@ class MipsO3CPU : public FullO3CPU<Impl>
}
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
+ void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg,
+ void setMiscReg(int misc_reg,
const TheISA::MiscReg &val, unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
diff --git a/src/cpu/o3/mips/cpu_impl.hh b/src/cpu/o3/mips/cpu_impl.hh
index e7dbd3aba..317fd748e 100644
--- a/src/cpu/o3/mips/cpu_impl.hh
+++ b/src/cpu/o3/mips/cpu_impl.hh
@@ -135,31 +135,31 @@ MipsO3CPU<Impl>::regStats()
template <class Impl>
MiscReg
-MipsO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
+MipsO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscReg(misc_reg, tid);
+ return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
MiscReg
-MipsO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
+MipsO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscRegWithEffect(misc_reg, tid);
+ return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
-MipsO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
+MipsO3CPU<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
{
- this->regFile.setMiscReg(misc_reg, val, tid);
+ this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
-MipsO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
+MipsO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val,
unsigned tid)
{
- this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
+ this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
diff --git a/src/cpu/o3/mips/dyn_inst.hh b/src/cpu/o3/mips/dyn_inst.hh
index f53530908..366b4bb23 100755
--- a/src/cpu/o3/mips/dyn_inst.hh
+++ b/src/cpu/o3/mips/dyn_inst.hh
@@ -93,32 +93,32 @@ class MipsDynInst : public BaseDynInst<Impl>
public:
/** Reads a miscellaneous register. */
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return this->cpu->readMiscReg(misc_reg, this->threadNumber);
+ return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
}
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
+ return this->cpu->readMiscReg(misc_reg, this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
this->instResult.integer = val;
- this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
+ this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
}
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(misc_reg, val,
+ return this->cpu->setMiscReg(misc_reg, val,
this->threadNumber);
}
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index 598af123e..c4f8f3a9f 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -225,26 +225,26 @@ class PhysRegFile
floatRegFile[reg_idx].q = val;
}
- MiscReg readMiscReg(int misc_reg, unsigned thread_id)
+ MiscReg readMiscRegNoEffect(int misc_reg, unsigned thread_id)
{
- return miscRegs[thread_id].readReg(misc_reg);
+ return miscRegs[thread_id].readRegNoEffect(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg, unsigned thread_id)
+ MiscReg readMiscReg(int misc_reg, unsigned thread_id)
{
- return miscRegs[thread_id].readRegWithEffect(misc_reg,
+ return miscRegs[thread_id].readReg(misc_reg,
cpu->tcBase(thread_id));
}
- void setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned thread_id)
{
- miscRegs[thread_id].setReg(misc_reg, val);
+ miscRegs[thread_id].setRegNoEffect(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val,
+ void setMiscReg(int misc_reg, const MiscReg &val,
unsigned thread_id)
{
- miscRegs[thread_id].setRegWithEffect(misc_reg, val,
+ miscRegs[thread_id].setReg(misc_reg, val,
cpu->tcBase(thread_id));
}
diff --git a/src/cpu/o3/sparc/cpu.hh b/src/cpu/o3/sparc/cpu.hh
index 08ebd2710..7b932e429 100644
--- a/src/cpu/o3/sparc/cpu.hh
+++ b/src/cpu/o3/sparc/cpu.hh
@@ -106,20 +106,20 @@ class SparcO3CPU : public FullO3CPU<Impl>
#endif
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
/** Sets a miscellaneous register. */
- void setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
+ void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val,
+ void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
unsigned tid);
/** Initiates a squash of all in-flight instructions for a given
diff --git a/src/cpu/o3/sparc/cpu_impl.hh b/src/cpu/o3/sparc/cpu_impl.hh
index c039a8fec..a425a8a56 100644
--- a/src/cpu/o3/sparc/cpu_impl.hh
+++ b/src/cpu/o3/sparc/cpu_impl.hh
@@ -153,32 +153,32 @@ SparcO3CPU<Impl>::regStats()
template <class Impl>
TheISA::MiscReg
-SparcO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
+SparcO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscReg(misc_reg, tid);
+ return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
TheISA::MiscReg
-SparcO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
+SparcO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
- return this->regFile.readMiscRegWithEffect(misc_reg, tid);
+ return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
-SparcO3CPU<Impl>::setMiscReg(int misc_reg,
+SparcO3CPU<Impl>::setMiscRegNoEffect(int misc_reg,
const SparcISA::MiscReg &val, unsigned tid)
{
- this->regFile.setMiscReg(misc_reg, val, tid);
+ this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
-SparcO3CPU<Impl>::setMiscRegWithEffect(int misc_reg,
+SparcO3CPU<Impl>::setMiscReg(int misc_reg,
const SparcISA::MiscReg &val, unsigned tid)
{
- this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
+ this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
diff --git a/src/cpu/o3/sparc/dyn_inst.hh b/src/cpu/o3/sparc/dyn_inst.hh
index 4314488b5..72242b161 100644
--- a/src/cpu/o3/sparc/dyn_inst.hh
+++ b/src/cpu/o3/sparc/dyn_inst.hh
@@ -77,39 +77,39 @@ class SparcDynInst : public BaseDynInst<Impl>
public:
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscReg(int misc_reg)
+ TheISA::MiscReg readMiscRegNoEffect(int misc_reg)
{
- return this->cpu->readMiscReg(misc_reg, this->threadNumber);
+ return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
}
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegWithEffect(int misc_reg)
+ TheISA::MiscReg readMiscReg(int misc_reg)
{
- return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber);
+ return this->cpu->readMiscReg(misc_reg, this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscReg(int misc_reg, const TheISA::MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val)
{
this->instResult.integer = val;
- return this->cpu->setMiscReg(misc_reg, val, this->threadNumber);
+ return this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
}
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val)
+ void setMiscReg(int misc_reg, const TheISA::MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(misc_reg, val,
+ return this->cpu->setMiscReg(misc_reg, val,
this->threadNumber);
}
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+ TheISA::MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
{
- return this->cpu->readMiscReg(
+ return this->cpu->readMiscRegNoEffect(
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
this->threadNumber);
}
@@ -117,19 +117,19 @@ class SparcDynInst : public BaseDynInst<Impl>
/** Reads a misc. register, including any side-effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+ TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
{
- return this->cpu->readMiscRegWithEffect(
+ return this->cpu->readMiscReg(
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
this->threadNumber);
}
/** Sets a misc. register. */
- void setMiscRegOperand(const StaticInst * si,
+ void setMiscRegOperandNoEffect(const StaticInst * si,
int idx, const TheISA::MiscReg &val)
{
this->instResult.integer = val;
- return this->cpu->setMiscReg(
+ return this->cpu->setMiscRegNoEffect(
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
val, this->threadNumber);
}
@@ -137,10 +137,10 @@ class SparcDynInst : public BaseDynInst<Impl>
/** Sets a misc. register, including any side-effects the write
* might have as defined by the architecture.
*/
- void setMiscRegOperandWithEffect(
+ void setMiscRegOperand(
const StaticInst *si, int idx, const TheISA::MiscReg &val)
{
- return this->cpu->setMiscRegWithEffect(
+ return this->cpu->setMiscReg(
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
val, this->threadNumber);
}
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index 4987d6eb4..93638673b 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -206,20 +206,20 @@ class O3ThreadContext : public ThreadContext
virtual void setNextPC(uint64_t val);
/** Reads a miscellaneous register. */
- virtual MiscReg readMiscReg(int misc_reg)
- { return cpu->readMiscReg(misc_reg, thread->readTid()); }
+ virtual MiscReg readMiscRegNoEffect(int misc_reg)
+ { return cpu->readMiscRegNoEffect(misc_reg, thread->readTid()); }
/** Reads a misc. register, including any side-effects the
* read might have as defined by the architecture. */
- virtual MiscReg readMiscRegWithEffect(int misc_reg)
- { return cpu->readMiscRegWithEffect(misc_reg, thread->readTid()); }
+ virtual MiscReg readMiscReg(int misc_reg)
+ { return cpu->readMiscReg(misc_reg, thread->readTid()); }
/** Sets a misc. register. */
- virtual void setMiscReg(int misc_reg, const MiscReg &val);
+ virtual void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
/** Sets a misc. register, including any side-effects the
* write might have as defined by the architecture. */
- virtual void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
+ virtual void setMiscReg(int misc_reg, const MiscReg &val);
/** Returns the number of consecutive store conditional failures. */
// @todo: Figure out where these store cond failures should go.
diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh
index af98fa1f5..a145e046e 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_impl.hh
@@ -103,7 +103,7 @@ void
O3ThreadContext<Impl>::delVirtPort(VirtualPort *vp)
{
if (vp != thread->getVirtPort()) {
- delete vp->getPeer();
+ vp->removeConn();
delete vp;
}
}
@@ -442,9 +442,9 @@ O3ThreadContext<Impl>::setNextPC(uint64_t val)
template <class Impl>
void
-O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
+O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
- cpu->setMiscReg(misc_reg, val, thread->readTid());
+ cpu->setMiscRegNoEffect(misc_reg, val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
@@ -454,10 +454,10 @@ O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
template <class Impl>
void
-O3ThreadContext<Impl>::setMiscRegWithEffect(int misc_reg,
+O3ThreadContext<Impl>::setMiscReg(int misc_reg,
const MiscReg &val)
{
- cpu->setMiscRegWithEffect(misc_reg, val, thread->readTid());
+ cpu->setMiscReg(misc_reg, val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
diff --git a/src/cpu/ozone/SConscript b/src/cpu/ozone/SConscript
new file mode 100644
index 000000000..4a040684a
--- /dev/null
+++ b/src/cpu/ozone/SConscript
@@ -0,0 +1,45 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+Import('*')
+
+if 'OzoneCPU' in env['CPU_MODELS']:
+ need_bp_unit = True
+ Source('base_dyn_inst.cc')
+ Source('bpred_unit.cc')
+ Source('cpu.cc')
+ Source('cpu_builder.cc')
+ Source('dyn_inst.cc')
+ Source('front_end.cc')
+ Source('lw_back_end.cc')
+ Source('lw_lsq.cc')
+ Source('rename_table.cc')
+ if env['USE_CHECKER']:
+ Source('checker_builder.cc')
diff --git a/src/cpu/ozone/SConsopts b/src/cpu/ozone/SConsopts
new file mode 100644
index 000000000..341644dcd
--- /dev/null
+++ b/src/cpu/ozone/SConsopts
@@ -0,0 +1,33 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+Import('*')
+
+all_cpu_list.append('OzoneCPU')
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index baea7a546..2432df55e 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -235,14 +235,14 @@ class OzoneCPU : public BaseCPU
public:
// ISA stuff:
+ MiscReg readMiscRegNoEffect(int misc_reg);
+
MiscReg readMiscReg(int misc_reg);
- MiscReg readMiscRegWithEffect(int misc_reg);
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
void setMiscReg(int misc_reg, const MiscReg &val);
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
-
unsigned readStCondFailures()
{ return thread->storeCondFailures; }
diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh
index a854de8de..d78162243 100644
--- a/src/cpu/ozone/cpu_impl.hh
+++ b/src/cpu/ozone/cpu_impl.hh
@@ -748,7 +748,7 @@ template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::delVirtPort(VirtualPort *vp)
{
- delete vp->getPeer();
+ vp->removeConn();
delete vp;
}
#endif
@@ -1089,24 +1089,24 @@ OzoneCPU<Impl>::OzoneTC::setNextPC(Addr val)
template <class Impl>
TheISA::MiscReg
-OzoneCPU<Impl>::OzoneTC::readMiscReg(int misc_reg)
+OzoneCPU<Impl>::OzoneTC::readMiscRegNoEffect(int misc_reg)
{
- return thread->miscRegFile.readReg(misc_reg);
+ return thread->miscRegFile.readRegNoEffect(misc_reg);
}
template <class Impl>
TheISA::MiscReg
-OzoneCPU<Impl>::OzoneTC::readMiscRegWithEffect(int misc_reg)
+OzoneCPU<Impl>::OzoneTC::readMiscReg(int misc_reg)
{
- return thread->miscRegFile.readRegWithEffect(misc_reg, this);
+ return thread->miscRegFile.readReg(misc_reg, this);
}
template <class Impl>
void
-OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
+OzoneCPU<Impl>::OzoneTC::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
// Needs to setup a squash event unless we're in syscall mode
- thread->miscRegFile.setReg(misc_reg, val);
+ thread->miscRegFile.setRegNoEffect(misc_reg, val);
if (!thread->inSyscall) {
cpu->squashFromTC();
@@ -1115,10 +1115,10 @@ OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
template <class Impl>
void
-OzoneCPU<Impl>::OzoneTC::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
{
// Needs to setup a squash event unless we're in syscall mode
- thread->miscRegFile.setRegWithEffect(misc_reg, val, this);
+ thread->miscRegFile.setReg(misc_reg, val, this);
if (!thread->inSyscall) {
cpu->squashFromTC();
diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh
index 88f96b14b..e138cbe13 100644
--- a/src/cpu/ozone/dyn_inst.hh
+++ b/src/cpu/ozone/dyn_inst.hh
@@ -231,14 +231,14 @@ class OzoneDynInst : public BaseDynInst<Impl>
public:
// ISA stuff
+ MiscReg readMiscRegNoEffect(int misc_reg);
+
MiscReg readMiscReg(int misc_reg);
- MiscReg readMiscRegWithEffect(int misc_reg);
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
void setMiscReg(int misc_reg, const MiscReg &val);
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val);
-
#if FULL_SYSTEM
Fault hwrei();
void trap(Fault fault);
diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh
index 05a66d77a..8519917f5 100644
--- a/src/cpu/ozone/dyn_inst_impl.hh
+++ b/src/cpu/ozone/dyn_inst_impl.hh
@@ -219,31 +219,31 @@ OzoneDynInst<Impl>::clearMemDependents()
template <class Impl>
TheISA::MiscReg
-OzoneDynInst<Impl>::readMiscReg(int misc_reg)
+OzoneDynInst<Impl>::readMiscRegNoEffect(int misc_reg)
{
- return this->thread->readMiscReg(misc_reg);
+ return this->thread->readMiscRegNoEffect(misc_reg);
}
template <class Impl>
TheISA::MiscReg
-OzoneDynInst<Impl>::readMiscRegWithEffect(int misc_reg)
+OzoneDynInst<Impl>::readMiscReg(int misc_reg)
{
- return this->thread->readMiscRegWithEffect(misc_reg);
+ return this->thread->readMiscReg(misc_reg);
}
template <class Impl>
void
-OzoneDynInst<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
+OzoneDynInst<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
this->setIntResult(val);
- this->thread->setMiscReg(misc_reg, val);
+ this->thread->setMiscRegNoEffect(misc_reg, val);
}
template <class Impl>
void
-OzoneDynInst<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+OzoneDynInst<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
{
- this->thread->setMiscRegWithEffect(misc_reg, val);
+ this->thread->setMiscReg(misc_reg, val);
}
#if FULL_SYSTEM
@@ -255,7 +255,7 @@ OzoneDynInst<Impl>::hwrei()
if (!(this->readPC() & 0x3))
return new AlphaISA::UnimplementedOpcodeFault;
- this->setNextPC(this->thread->readMiscReg(AlphaISA::IPR_EXC_ADDR));
+ this->setNextPC(this->thread->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR));
this->cpu->hwrei();
diff --git a/src/cpu/ozone/inorder_back_end_impl.hh b/src/cpu/ozone/inorder_back_end_impl.hh
index 84f935a72..8d7ebb60e 100644
--- a/src/cpu/ozone/inorder_back_end_impl.hh
+++ b/src/cpu/ozone/inorder_back_end_impl.hh
@@ -89,13 +89,13 @@ InorderBackEnd<Impl>::checkInterrupts()
int summary = 0;
- if (thread->readMiscReg(IPR_ASTRR))
+ if (thread->readMiscRegNoEffect(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
- if (thread->readMiscReg(IPR_SIRR)) {
+ if (thread->readMiscRegNoEffect(IPR_SIRR)) {
for (int i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
+ if (thread->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of the 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
@@ -116,14 +116,14 @@ InorderBackEnd<Impl>::checkInterrupts()
}
}
- if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) {
+ if (ipl && ipl > thread->readMiscRegNoEffect(IPR_IPLR)) {
thread->inSyscall = true;
- thread->setMiscReg(IPR_ISR, summary);
- thread->setMiscReg(IPR_INTID, ipl);
+ thread->setMiscRegNoEffect(IPR_ISR, summary);
+ thread->setMiscRegNoEffect(IPR_INTID, ipl);
Fault(new InterruptFault)->invoke(xc);
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- thread->readMiscReg(IPR_IPLR), ipl, summary);
+ thread->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
// May need to go 1 inst prior
squashPending = true;
diff --git a/src/cpu/ozone/inst_queue_impl.hh b/src/cpu/ozone/inst_queue_impl.hh
index 84f2b2a19..ea9d03c0d 100644
--- a/src/cpu/ozone/inst_queue_impl.hh
+++ b/src/cpu/ozone/inst_queue_impl.hh
@@ -38,7 +38,7 @@
#include <vector>
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "cpu/ozone/inst_queue.hh"
#if 0
diff --git a/src/cpu/ozone/lw_back_end_impl.hh b/src/cpu/ozone/lw_back_end_impl.hh
index a181c93f4..c0a9cad24 100644
--- a/src/cpu/ozone/lw_back_end_impl.hh
+++ b/src/cpu/ozone/lw_back_end_impl.hh
@@ -1193,7 +1193,7 @@ LWBackEnd<Impl>::commitInst(int inst_num)
#if FULL_SYSTEM
if (thread->profile) {
// bool usermode =
-// (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+// (xc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
// thread->profilePC = usermode ? 1 : inst->readPC();
thread->profilePC = inst->readPC();
ProfileNode *node = thread->profile->consume(thread->getTC(),
diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh
index ee1968626..f26b06453 100644
--- a/src/cpu/ozone/lw_lsq_impl.hh
+++ b/src/cpu/ozone/lw_lsq_impl.hh
@@ -605,12 +605,12 @@ OzoneLWLSQ<Impl>::writebackStores()
// @todo: Remove this SC hack once the memory system handles it.
if (req->isLocked()) {
if (req->isUncacheable()) {
- req->setScResult(2);
+ req->setExtraData(2);
} else {
if (cpu->lockFlag) {
- req->setScResult(1);
+ req->setExtraData(1);
} else {
- req->setScResult(0);
+ req->setExtraData(0);
// Hack: Instantly complete this store.
completeDataAccess(data_pkt);
--sq_it;
diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh
index a71795851..53776e7d9 100644
--- a/src/cpu/ozone/thread_state.hh
+++ b/src/cpu/ozone/thread_state.hh
@@ -115,24 +115,24 @@ struct OzoneThreadState : public ThreadState {
ThreadContext *getTC() { return tc; }
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return miscRegFile.readReg(misc_reg);
+ return miscRegFile.readRegNoEffect(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return miscRegFile.readRegWithEffect(misc_reg, tc);
+ return miscRegFile.readReg(misc_reg, tc);
}
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
- miscRegFile.setReg(misc_reg, val);
+ miscRegFile.setRegNoEffect(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
- miscRegFile.setRegWithEffect(misc_reg, val, tc);
+ miscRegFile.setReg(misc_reg, val, tc);
}
uint64_t readPC()
diff --git a/src/cpu/pc_event.cc b/src/cpu/pc_event.cc
index fca357fe3..438218df2 100644
--- a/src/cpu/pc_event.cc
+++ b/src/cpu/pc_event.cc
@@ -40,7 +40,7 @@
#include "cpu/thread_context.hh"
#include "cpu/pc_event.hh"
#include "sim/debug.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
#include "sim/system.hh"
using namespace std;
@@ -138,14 +138,12 @@ BreakPCEvent::process(ThreadContext *tc)
}
#if FULL_SYSTEM
-extern "C"
void
sched_break_pc_sys(System *sys, Addr addr)
{
new BreakPCEvent(&sys->pcEventQueue, "debug break", addr, true);
}
-extern "C"
void
sched_break_pc(Addr addr)
{
diff --git a/src/cpu/simple/SConscript b/src/cpu/simple/SConscript
new file mode 100644
index 000000000..9a6a80473
--- /dev/null
+++ b/src/cpu/simple/SConscript
@@ -0,0 +1,43 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+Import('*')
+
+need_simple_base = False
+if 'AtomicSimpleCPU' in env['CPU_MODELS']:
+ need_simple_base = True
+ Source('atomic.cc')
+
+if 'TimingSimpleCPU' in env['CPU_MODELS']:
+ need_simple_base = True
+ Source('timing.cc')
+
+if need_simple_base:
+ Source('base.cc')
diff --git a/src/cpu/simple/SConsopts b/src/cpu/simple/SConsopts
new file mode 100644
index 000000000..32dbda1a5
--- /dev/null
+++ b/src/cpu/simple/SConsopts
@@ -0,0 +1,34 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+Import('*')
+
+all_cpu_list.extend(('AtomicSimpleCPU', 'TimingSimpleCPU'))
+default_cpus.extend(('AtomicSimpleCPU', 'TimingSimpleCPU'))
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 3b3536e44..6f69b5ac4 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -31,6 +31,7 @@
#include "arch/locked_mem.hh"
#include "arch/mmaped_ipr.hh"
#include "arch/utility.hh"
+#include "base/bigint.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/atomic.hh"
#include "mem/packet.hh"
@@ -125,6 +126,17 @@ AtomicSimpleCPU::CpuPort::recvRetry()
panic("AtomicSimpleCPU doesn't expect recvRetry callback!");
}
+void
+AtomicSimpleCPU::DcachePort::setPeer(Port *port)
+{
+ Port::setPeer(port);
+
+#if FULL_SYSTEM
+ // Update the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ cpu->tcBase()->connectMemPorts();
+#endif
+}
AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
: BaseSimpleCPU(p), tickEvent(this),
@@ -138,18 +150,20 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
ifetch_req = new Request();
ifetch_req->setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT
- ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
+ ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
ifetch_pkt->dataStatic(&inst);
data_read_req = new Request();
data_read_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
- data_read_pkt = new Packet(data_read_req, Packet::ReadReq,
+ data_read_pkt = new Packet(data_read_req, MemCmd::ReadReq,
Packet::Broadcast);
data_read_pkt->dataStatic(&dataReg);
data_write_req = new Request();
data_write_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
- data_write_pkt = new Packet(data_write_req, Packet::WriteReq,
+ data_write_pkt = new Packet(data_write_req, MemCmd::WriteReq,
+ Packet::Broadcast);
+ data_swap_pkt = new Packet(data_write_req, MemCmd::SwapReq,
Packet::Broadcast);
}
@@ -208,7 +222,7 @@ AtomicSimpleCPU::switchOut()
void
AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
{
- BaseCPU::takeOverFrom(oldCPU);
+ BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
assert(!tickEvent.scheduled());
@@ -239,12 +253,6 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay)
notIdleFraction++;
-#if FULL_SYSTEM
- // Connect the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- tc->connectMemPorts();
-#endif
-
//Make sure ticks are still on multiples of cycles
tickEvent.schedule(nextCycle(curTick + cycles(delay)));
_status = Running;
@@ -318,6 +326,14 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
template
Fault
+AtomicSimpleCPU::read(Addr addr, Twin32_t &data, unsigned flags);
+
+template
+Fault
+AtomicSimpleCPU::read(Addr addr, Twin64_t &data, unsigned flags);
+
+template
+Fault
AtomicSimpleCPU::read(Addr addr, uint64_t &data, unsigned flags);
template
@@ -363,10 +379,15 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
// use the CPU's statically allocated write request and packet objects
Request *req = data_write_req;
- PacketPtr pkt = data_write_pkt;
+ PacketPtr pkt;
req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
+ if (req->isSwap())
+ pkt = data_swap_pkt;
+ else
+ pkt = data_write_pkt;
+
if (traceData) {
traceData->setAddr(addr);
}
@@ -381,6 +402,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
if (req->isLocked()) {
do_access = TheISA::handleLockedWrite(thread, req);
}
+ if (req->isCondSwap()) {
+ assert(res);
+ req->setExtraData(*res);
+ }
+
if (do_access) {
pkt->reinitFromRequest();
@@ -401,15 +427,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
#endif
}
- if (req->isLocked()) {
- uint64_t scResult = req->getScResult();
- if (scResult != 0) {
- // clear failure counter
- thread->setStCondFailures(0);
- }
- if (res) {
- *res = req->getScResult();
- }
+ if (req->isSwap()) {
+ assert(res);
+ *res = pkt->get<T>();
+ } else if (res) {
+ *res = req->getExtraData();
}
}
@@ -424,6 +446,17 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+template
+Fault
+AtomicSimpleCPU::write(Twin32_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
+template
+Fault
+AtomicSimpleCPU::write(Twin64_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
template
Fault
AtomicSimpleCPU::write(uint64_t data, Addr addr,
@@ -483,17 +516,28 @@ AtomicSimpleCPU::tick()
Fault fault = setupFetchRequest(ifetch_req);
if (fault == NoFault) {
- ifetch_pkt->reinitFromRequest();
+ Tick icache_latency = 0;
+ bool icache_access = false;
+ dcache_access = false; // assume no dcache access
- Tick icache_latency = icachePort.sendAtomic(ifetch_pkt);
- // ifetch_req is initialized to read the instruction directly
- // into the CPU object's inst field.
+ //Fetch more instruction memory if necessary
+ if(predecoder.needMoreBytes())
+ {
+ icache_access = true;
+ ifetch_pkt->reinitFromRequest();
+
+ icache_latency = icachePort.sendAtomic(ifetch_pkt);
+ // ifetch_req is initialized to read the instruction directly
+ // into the CPU object's inst field.
+ }
- dcache_access = false; // assume no dcache access
preExecute();
- fault = curStaticInst->execute(this, traceData);
- postExecute();
+ if(curStaticInst)
+ {
+ fault = curStaticInst->execute(this, traceData);
+ postExecute();
+ }
// @todo remove me after debugging with legion done
if (curStaticInst && (!curStaticInst->isMicroOp() ||
@@ -501,7 +545,8 @@ AtomicSimpleCPU::tick()
instCnt++;
if (simulate_stalls) {
- Tick icache_stall = icache_latency - cycles(1);
+ Tick icache_stall =
+ icache_access ? icache_latency - cycles(1) : 0;
Tick dcache_stall =
dcache_access ? dcache_latency - cycles(1) : 0;
Tick stall_cycles = (icache_stall + dcache_stall) / cycles(1);
@@ -512,8 +557,8 @@ AtomicSimpleCPU::tick()
}
}
-
- advancePC(fault);
+ if(predecoder.needMoreBytes())
+ advancePC(fault);
}
if (_status != Idle)
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index 42c7bf23a..ad4aa4708 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -81,9 +81,6 @@ class AtomicSimpleCPU : public BaseSimpleCPU
class CpuPort : public Port
{
-
- AtomicSimpleCPU *cpu;
-
public:
CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu)
@@ -94,6 +91,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
protected:
+ AtomicSimpleCPU *cpu;
+
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt);
@@ -110,7 +109,17 @@ class AtomicSimpleCPU : public BaseSimpleCPU
};
CpuPort icachePort;
- CpuPort dcachePort;
+
+ class DcachePort : public CpuPort
+ {
+ public:
+ DcachePort(const std::string &_name, AtomicSimpleCPU *_cpu)
+ : CpuPort(_name, _cpu)
+ { }
+
+ virtual void setPeer(Port *port);
+ };
+ DcachePort dcachePort;
Request *ifetch_req;
PacketPtr ifetch_pkt;
@@ -118,6 +127,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
PacketPtr data_read_pkt;
Request *data_write_req;
PacketPtr data_write_pkt;
+ PacketPtr data_swap_pkt;
bool dcache_access;
Tick dcache_latency;
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index b8d1f3bed..877dc5bd4 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -70,7 +70,7 @@ using namespace std;
using namespace TheISA;
BaseSimpleCPU::BaseSimpleCPU(Params *p)
- : BaseCPU(p), thread(NULL)
+ : BaseCPU(p), thread(NULL), predecoder(NULL)
{
#if FULL_SYSTEM
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
@@ -301,7 +301,7 @@ BaseSimpleCPU::post_interrupt(int int_num, int index)
BaseCPU::post_interrupt(int_num, index);
if (thread->status() == ThreadContext::Suspended) {
- DPRINTF(IPI,"Suspended Processor awoke\n");
+ DPRINTF(Quiesce,"Suspended Processor awoke\n");
thread->activate();
}
}
@@ -367,16 +367,23 @@ BaseSimpleCPU::preExecute()
inst = gtoh(inst);
//If we're not in the middle of a macro instruction
if (!curMacroStaticInst) {
-#if THE_ISA == ALPHA_ISA
- StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC()));
-#elif THE_ISA == SPARC_ISA
- StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC()));
-#elif THE_ISA == MIPS_ISA
- //Mips doesn't do anything in it's MakeExtMI function right now,
- //so it won't be called.
- StaticInstPtr instPtr = StaticInst::decode(inst);
-#endif
- if (instPtr->isMacroOp()) {
+ StaticInstPtr instPtr = NULL;
+
+ //Predecode, ie bundle up an ExtMachInst
+ //This should go away once the constructor can be set up properly
+ predecoder.setTC(thread->getTC());
+ //If more fetch data is needed, pass it in.
+ if(predecoder.needMoreBytes())
+ predecoder.moreBytes(thread->readPC(), 0, inst);
+ else
+ predecoder.process();
+ //If an instruction is ready, decode it
+ if (predecoder.extMachInstReady())
+ instPtr = StaticInst::decode(predecoder.getExtMachInst());
+
+ //If we decoded an instruction and it's microcoded, start pulling
+ //out micro ops
+ if (instPtr && instPtr->isMacroOp()) {
curMacroStaticInst = instPtr;
curStaticInst = curMacroStaticInst->
fetchMicroOp(thread->readMicroPC());
@@ -389,17 +396,19 @@ BaseSimpleCPU::preExecute()
fetchMicroOp(thread->readMicroPC());
}
+ //If we decoded an instruction this "tick", record information about it.
+ if(curStaticInst)
+ {
+ traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
+ thread->readPC());
- traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
- thread->readPC());
-
- DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
- curStaticInst->getName(), curStaticInst->getOpcode(),
- curStaticInst->machInst);
+ DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
+ curStaticInst->getName(), curStaticInst->machInst);
#if FULL_SYSTEM
- thread->setInst(inst);
+ thread->setInst(inst);
#endif // FULL_SYSTEM
+ }
}
void
@@ -409,7 +418,8 @@ BaseSimpleCPU::postExecute()
if (thread->profile) {
bool usermode = TheISA::inUserMode(tc);
thread->profilePC = usermode ? 1 : thread->readPC();
- ProfileNode *node = thread->profile->consume(tc, inst);
+ StaticInstPtr si(inst);
+ ProfileNode *node = thread->profile->consume(tc, si);
if (node)
thread->profileNode = node;
}
@@ -427,7 +437,9 @@ BaseSimpleCPU::postExecute()
traceFunctions(thread->readPC());
if (traceData) {
- traceData->finalize();
+ traceData->dump();
+ delete traceData;
+ traceData = NULL;
}
}
@@ -440,9 +452,9 @@ BaseSimpleCPU::advancePC(Fault fault)
fault->invoke(tc);
thread->setMicroPC(0);
thread->setNextMicroPC(1);
- } else {
+ } else if (predecoder.needMoreBytes()) {
//If we're at the last micro op for this instruction
- if (curStaticInst->isLastMicroOp()) {
+ if (curStaticInst && curStaticInst->isLastMicroOp()) {
//We should be working with a macro op
assert(curMacroStaticInst);
//Close out this macro op, and clean up the
@@ -461,13 +473,9 @@ BaseSimpleCPU::advancePC(Fault fault)
} else {
// go to the next instruction
thread->setPC(thread->readNextPC());
-#if ISA_HAS_DELAY_SLOT
thread->setNextPC(thread->readNextNPC());
thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
assert(thread->readNextPC() != thread->readNextNPC());
-#else
- thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
-#endif
}
}
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index c4853b916..787259c96 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -33,6 +33,7 @@
#ifndef __CPU_SIMPLE_BASE_HH__
#define __CPU_SIMPLE_BASE_HH__
+#include "arch/predecoder.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
@@ -63,6 +64,10 @@ class Process;
class RemoteGDB;
class GDBListener;
+namespace TheISA
+{
+ class Predecoder;
+}
class ThreadContext;
class Checkpoint;
@@ -74,7 +79,6 @@ namespace Trace {
class BaseSimpleCPU : public BaseCPU
{
protected:
- typedef TheISA::MachInst MachInst;
typedef TheISA::MiscReg MiscReg;
typedef TheISA::FloatReg FloatReg;
typedef TheISA::FloatRegBits FloatRegBits;
@@ -122,10 +126,13 @@ class BaseSimpleCPU : public BaseCPU
#endif
// current instruction
- MachInst inst;
+ TheISA::MachInst inst;
+
+ // The predecoder
+ TheISA::Predecoder predecoder;
// Static data storage
- TheISA::IntReg dataReg;
+ TheISA::LargestRead dataReg;
StaticInstPtr curStaticInst;
StaticInstPtr curMacroStaticInst;
@@ -284,14 +291,19 @@ class BaseSimpleCPU : public BaseCPU
void setNextPC(uint64_t val) { thread->setNextPC(val); }
void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
+ MiscReg readMiscRegNoEffect(int misc_reg)
+ {
+ return thread->readMiscRegNoEffect(misc_reg);
+ }
+
MiscReg readMiscReg(int misc_reg)
{
return thread->readMiscReg(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
- return thread->readMiscRegWithEffect(misc_reg);
+ return thread->setMiscRegNoEffect(misc_reg, val);
}
void setMiscReg(int misc_reg, const MiscReg &val)
@@ -299,9 +311,10 @@ class BaseSimpleCPU : public BaseCPU
return thread->setMiscReg(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
{
- return thread->setMiscRegWithEffect(misc_reg, val);
+ int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+ return thread->readMiscRegNoEffect(reg_idx);
}
MiscReg readMiscRegOperand(const StaticInst *si, int idx)
@@ -310,23 +323,25 @@ class BaseSimpleCPU : public BaseCPU
return thread->readMiscReg(reg_idx);
}
- MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
+ void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val)
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
- return thread->readMiscRegWithEffect(reg_idx);
+ int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+ return thread->setMiscRegNoEffect(reg_idx, val);
}
- void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val)
+ void setMiscRegOperand(
+ const StaticInst *si, int idx, const MiscReg &val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
return thread->setMiscReg(reg_idx, val);
}
- void setMiscRegOperandWithEffect(
- const StaticInst *si, int idx, const MiscReg &val)
- {
- int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
- return thread->setMiscRegWithEffect(reg_idx, val);
+ unsigned readStCondFailures() {
+ return thread->readStCondFailures();
+ }
+
+ void setStCondFailures(unsigned sc_failures) {
+ thread->setStCondFailures(sc_failures);
}
#if FULL_SYSTEM
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index dfffb0b1f..45da7c3eb 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -30,6 +30,7 @@
#include "arch/locked_mem.hh"
#include "arch/utility.hh"
+#include "base/bigint.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/timing.hh"
#include "mem/packet.hh"
@@ -193,7 +194,7 @@ TimingSimpleCPU::switchOut()
void
TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
{
- BaseCPU::takeOverFrom(oldCPU);
+ BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
// if any of this CPU's ThreadContexts are active, mark the CPU as
// running and schedule its tick event.
@@ -208,23 +209,6 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
if (_status != Running) {
_status = Idle;
}
-
- Port *peer;
- if (icachePort.getPeer() == NULL) {
- peer = oldCPU->getPort("icache_port")->getPeer();
- icachePort.setPeer(peer);
- } else {
- peer = icachePort.getPeer();
- }
- peer->setPeer(&icachePort);
-
- if (dcachePort.getPeer() == NULL) {
- peer = oldCPU->getPort("dcache_port")->getPeer();
- dcachePort.setPeer(peer);
- } else {
- peer = dcachePort.getPeer();
- }
- peer->setPeer(&dcachePort);
}
@@ -239,12 +223,6 @@ TimingSimpleCPU::activateContext(int thread_num, int delay)
notIdleFraction++;
_status = Running;
-#if FULL_SYSTEM
- // Connect the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- tc->connectMemPorts();
-#endif
-
// kick things off by initiating the fetch of the next instruction
fetchEvent =
new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false);
@@ -286,7 +264,7 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// Now do the access.
if (fault == NoFault) {
PacketPtr pkt =
- new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
pkt->dataDynamic<T>(new T);
if (!dcachePort.sendTiming(pkt)) {
@@ -297,14 +275,14 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// memory system takes ownership of packet
dcache_pkt = NULL;
}
+
+ // This will need a new way to tell if it has a dcache attached.
+ if (req->isUncacheable())
+ recordEvent("Uncached Read");
} else {
delete req;
}
- // This will need a new way to tell if it has a dcache attached.
- if (req->isUncacheable())
- recordEvent("Uncached Read");
-
return fault;
}
@@ -312,6 +290,14 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
template
Fault
+TimingSimpleCPU::read(Addr addr, Twin64_t &data, unsigned flags);
+
+template
+Fault
+TimingSimpleCPU::read(Addr addr, Twin32_t &data, unsigned flags);
+
+template
+Fault
TimingSimpleCPU::read(Addr addr, uint64_t &data, unsigned flags);
template
@@ -359,13 +345,20 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(),
cpu_id, /* thread ID */ 0);
+ if (traceData) {
+ traceData->setAddr(req->getVaddr());
+ }
+
// translate to physical address
Fault fault = thread->translateDataWriteReq(req);
// Now do the access.
if (fault == NoFault) {
assert(dcache_pkt == NULL);
- dcache_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ if (req->isSwap())
+ dcache_pkt = new Packet(req, MemCmd::SwapReq, Packet::Broadcast);
+ else
+ dcache_pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
dcache_pkt->allocate();
dcache_pkt->set(data);
@@ -374,6 +367,10 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
if (req->isLocked()) {
do_access = TheISA::handleLockedWrite(thread, req);
}
+ if (req->isCondSwap()) {
+ assert(res);
+ req->setExtraData(*res);
+ }
if (do_access) {
if (!dcachePort.sendTiming(dcache_pkt)) {
@@ -384,13 +381,13 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
dcache_pkt = NULL;
}
}
+ // This will need a new way to tell if it's hooked up to a cache or not.
+ if (req->isUncacheable())
+ recordEvent("Uncached Write");
} else {
delete req;
}
- // This will need a new way to tell if it's hooked up to a cache or not.
- if (req->isUncacheable())
- recordEvent("Uncached Write");
// If the write needs to have a fault on the access, consider calling
// changeStatus() and changing it to "bad addr write" or something.
@@ -401,6 +398,16 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template
Fault
+TimingSimpleCPU::write(Twin32_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
+template
+Fault
+TimingSimpleCPU::write(Twin64_t data, Addr addr,
+ unsigned flags, uint64_t *res);
+
+template
+Fault
TimingSimpleCPU::write(uint64_t data, Addr addr,
unsigned flags, uint64_t *res);
@@ -454,7 +461,7 @@ TimingSimpleCPU::fetch()
ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0);
Fault fault = setupFetchRequest(ifetch_req);
- ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
+ ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
ifetch_pkt->dataStatic(&inst);
if (fault == NoFault) {
@@ -629,6 +636,18 @@ TimingSimpleCPU::completeDrain()
drainEvent->process();
}
+void
+TimingSimpleCPU::DcachePort::setPeer(Port *port)
+{
+ Port::setPeer(port);
+
+#if FULL_SYSTEM
+ // Update the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ cpu->tcBase()->connectMemPorts();
+#endif
+}
+
bool
TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
{
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index abcb224bf..ef062d24a 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -144,6 +144,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
: CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu)
{ }
+ virtual void setPeer(Port *port);
+
protected:
virtual bool recvTiming(PacketPtr pkt);
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index 13d0e2e29..39f31782b 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -305,7 +305,7 @@ void
SimpleThread::delVirtPort(VirtualPort *vp)
{
if (vp != virtPort) {
- delete vp->getPeer();
+ vp->removeConn();
delete vp;
}
}
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index f2f79c070..824914ad0 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -350,24 +350,24 @@ class SimpleThread : public ThreadState
regs.setNextNPC(val);
}
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg)
{
- return regs.readMiscReg(misc_reg);
+ return regs.readMiscRegNoEffect(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg)
+ MiscReg readMiscReg(int misc_reg)
{
- return regs.readMiscRegWithEffect(misc_reg, tc);
+ return regs.readMiscReg(misc_reg, tc);
}
- void setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
- return regs.setMiscReg(misc_reg, val);
+ return regs.setMiscRegNoEffect(misc_reg, val);
}
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val)
{
- return regs.setMiscRegWithEffect(misc_reg, val, tc);
+ return regs.setMiscReg(misc_reg, val, tc);
}
unsigned readStCondFailures() { return storeCondFailures; }
diff --git a/src/cpu/static_inst.cc b/src/cpu/static_inst.cc
index cb4a7cdf7..64fcc0580 100644
--- a/src/cpu/static_inst.cc
+++ b/src/cpu/static_inst.cc
@@ -31,7 +31,7 @@
#include <iostream>
#include "cpu/static_inst.hh"
-#include "sim/root.hh"
+#include "sim/core.hh"
StaticInstPtr StaticInst::nullStaticInstPtr;
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 416c8ab56..a58ac85d6 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -35,6 +35,7 @@
#include <string>
#include "arch/isa_traits.hh"
+#include "arch/utility.hh"
#include "sim/faults.hh"
#include "base/bitfield.hh"
#include "base/hashmap.hh"
@@ -439,9 +440,6 @@ class StaticInst : public StaticInstBase
//This is defined as inline below.
static StaticInstPtr decode(ExtMachInst mach_inst);
- /// Return opcode of machine instruction
- uint32_t getOpcode() { return bits(machInst, 31, 26);}
-
/// Return name of machine instruction
std::string getName() { return mnemonic; }
};
@@ -474,7 +472,7 @@ class StaticInstPtr : public RefCountingPtr<StaticInst>
/// Construct directly from machine instruction.
/// Calls StaticInst::decode().
- StaticInstPtr(TheISA::ExtMachInst mach_inst)
+ explicit StaticInstPtr(TheISA::ExtMachInst mach_inst)
: RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
{
}
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index 16e491fd3..05c409c95 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -226,14 +226,14 @@ class ThreadContext
virtual void setNextNPC(uint64_t val) = 0;
+ virtual MiscReg readMiscRegNoEffect(int misc_reg) = 0;
+
virtual MiscReg readMiscReg(int misc_reg) = 0;
- virtual MiscReg readMiscRegWithEffect(int misc_reg) = 0;
+ virtual void setMiscRegNoEffect(int misc_reg, const MiscReg &val) = 0;
virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0;
- virtual void setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0;
-
// Also not necessarily the best location for these two. Hopefully will go
// away once we decide upon where st cond failures goes.
virtual unsigned readStCondFailures() = 0;
@@ -254,6 +254,8 @@ class ThreadContext
// Same with st cond failures.
virtual Counter readFuncExeInst() = 0;
+ virtual void syscall(int64_t callnum) = 0;
+
// This function exits the thread context in the CPU and returns
// 1 if the CPU has no more active threads (meaning it's OK to exit);
// Used in syscall-emulation mode when a thread calls the exit syscall.
@@ -410,18 +412,18 @@ class ProxyThreadContext : public ThreadContext
void setNextNPC(uint64_t val) { actualTC->setNextNPC(val); }
+ MiscReg readMiscRegNoEffect(int misc_reg)
+ { return actualTC->readMiscRegNoEffect(misc_reg); }
+
MiscReg readMiscReg(int misc_reg)
{ return actualTC->readMiscReg(misc_reg); }
- MiscReg readMiscRegWithEffect(int misc_reg)
- { return actualTC->readMiscRegWithEffect(misc_reg); }
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
+ { return actualTC->setMiscRegNoEffect(misc_reg, val); }
void setMiscReg(int misc_reg, const MiscReg &val)
{ return actualTC->setMiscReg(misc_reg, val); }
- void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
- { return actualTC->setMiscRegWithEffect(misc_reg, val); }
-
unsigned readStCondFailures()
{ return actualTC->readStCondFailures(); }
@@ -441,6 +443,9 @@ class ProxyThreadContext : public ThreadContext
void setSyscallReturn(SyscallReturn return_value)
{ actualTC->setSyscallReturn(return_value); }
+ void syscall(int64_t callnum)
+ { actualTC->syscall(callnum); }
+
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
#endif
diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc
index 93dd1e2eb..4b65ca4b8 100644
--- a/src/cpu/thread_state.cc
+++ b/src/cpu/thread_state.cc
@@ -125,7 +125,10 @@ ThreadState::connectPhysPort()
// @todo: For now this disregards any older port that may have
// already existed. Fix this memory leak once the bus port IDs
// for functional ports is resolved.
- physPort = new FunctionalPort(csprintf("%s-%d-funcport",
+ if (physPort)
+ physPort->removeConn();
+ else
+ physPort = new FunctionalPort(csprintf("%s-%d-funcport",
baseCpu->name(), tid));
connectToMemFunc(physPort);
}
@@ -136,7 +139,10 @@ ThreadState::connectVirtPort()
// @todo: For now this disregards any older port that may have
// already existed. Fix this memory leak once the bus port IDs
// for functional ports is resolved.
- virtPort = new VirtualPort(csprintf("%s-%d-vport",
+ if (virtPort)
+ virtPort->removeConn();
+ else
+ virtPort = new VirtualPort(csprintf("%s-%d-vport",
baseCpu->name(), tid));
connectToMemFunc(virtPort);
}
diff --git a/src/cpu/trace/SConscript b/src/cpu/trace/SConscript
new file mode 100644
index 000000000..f166b2f23
--- /dev/null
+++ b/src/cpu/trace/SConscript
@@ -0,0 +1,40 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+Import('*')
+
+if False:
+ Source('opt_cpu.cc')
+ Source('trace_cpu.cc')
+
+ Source('reader/mem_trace_reader.cc')
+ Source('reader/ibm_reader.cc')
+ Source('reader/itx_reader.cc')
+ Source('reader/m5_reader.cc')