Merge zizzer:/bk/newmem

into  zeep.eecs.umich.edu:/z/saidi/work/m5.newmem

--HG--
extra : convert_revision : c8670f1a39d6826870ca0934587f4cc71c94b0ab
This commit is contained in:
Ali Saidi
2006-06-17 17:17:43 -04:00
57 changed files with 1150 additions and 452 deletions

View File

@@ -39,17 +39,20 @@
#
# You can build M5 in a different directory as long as there is a
# 'build/<CONFIG>' somewhere along the target path. The build system
# expdects that all configs under the same build directory are being
# expects that all configs under the same build directory are being
# built for the same host system.
#
# Examples:
# These two commands are equivalent. The '-u' option tells scons to
# search up the directory tree for this SConstruct file.
#
# The following two commands are equivalent. The '-u' option tells
# scons to search up the directory tree for this SConstruct file.
# % cd <path-to-src>/m5 ; scons build/ALPHA_FS/m5.debug
# % cd <path-to-src>/m5/build/ALPHA_FS; scons -u m5.debug
# These two commands are equivalent and demonstrate building in a
# directory outside of the source tree. The '-C' option tells scons
# to chdir to the specified directory to find this SConstruct file.
#
# The following two commands are equivalent and demonstrate building
# in a directory outside of the source tree. The '-C' option tells
# scons to chdir to the specified directory to find this SConstruct
# file.
# % cd <path-to-src>/m5 ; scons /local/foo/build/ALPHA_FS/m5.debug
# % cd /local/foo/build/ALPHA_FS; scons -C <path-to-src>/m5 m5.debug
#
@@ -260,8 +263,8 @@ env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips']
# Define the universe of supported CPU models
env['ALL_CPU_LIST'] = ['AtomicSimpleCPU', 'TimingSimpleCPU',
'FullCPU', 'AlphaFullCPU',
'OzoneSimpleCPU', 'OzoneCPU', 'CheckerCPU']
'FullCPU', 'AlphaO3CPU',
'OzoneSimpleCPU', 'OzoneCPU']
# Sticky options get saved in the options file so they persist from
# one invocation to the next (unless overridden, in which case the new
@@ -289,6 +292,7 @@ sticky_opts.AddOptions(
False),
BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
BoolOption('USE_CHECKER', 'Use checker for detailed CPU models', False),
('CC', 'C compiler', os.environ.get('CC', env['CC'])),
('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])),
BoolOption('BATCH', 'Use batch pool for build and tests', False),
@@ -301,9 +305,10 @@ nonsticky_opts.AddOptions(
BoolOption('update_ref', 'Update test reference outputs', False)
)
# These options get exported to #defines in config/*.hh (see m5/SConscript).
# These options get exported to #defines in config/*.hh (see src/SConscript).
env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP']
'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP', \
'USE_CHECKER']
# Define a handy 'no-op' action
def no_action(target, source, env):
@@ -470,6 +475,10 @@ for build_path in build_paths:
env.ParseConfig(mysql_config_libs)
env.ParseConfig(mysql_config_include)
# Check if the Checker is being used. If so append it to env['CPU_MODELS']
if env['USE_CHECKER']:
env['CPU_MODELS'].append('CheckerCPU')
# Save sticky option settings back to current options file
sticky_opts.Save(current_opts_file, env)
@@ -482,7 +491,7 @@ for build_path in build_paths:
if env['USE_SSE2']:
env.Append(CCFLAGS='-msse2')
# The m5/SConscript file sets up the build rules in 'env' according
# The src/SConscript file sets up the build rules in 'env' according
# to the configured options. It returns a list of environments,
# one for each variant build (debug, opt, etc.)
envList = SConscript('src/SConscript', build_dir = build_path,

View File

@@ -8,6 +8,7 @@ parser = optparse.OptionParser(option_list=m5.standardOptions)
parser.add_option("-t", "--timing", action="store_true")
(options, args) = parser.parse_args()
m5.setStandardOptions(options)
if args:
print "Error: script doesn't take any positional arguments"

View File

@@ -13,9 +13,11 @@ parser = optparse.OptionParser(option_list=m5.standardOptions)
parser.add_option("-c", "--cmd", default="hello")
parser.add_option("-t", "--timing", action="store_true")
parser.add_option("-f", "--full", action="store_true")
parser.add_option("-d", "--detailed", action="store_true")
parser.add_option("-m", "--maxtick", type="int")
(options, args) = parser.parse_args()
m5.setStandardOptions(options)
if args:
print "Error: script doesn't take any positional arguments"
@@ -33,8 +35,8 @@ mem = PhysicalMemory()
if options.timing:
cpu = TimingSimpleCPU()
elif options.full:
cpu = DetailedCPU()
elif options.detailed:
cpu = DetailedO3CPU()
else:
cpu = AtomicSimpleCPU()
cpu.workload = process
@@ -48,7 +50,10 @@ root = Root(system = system)
m5.instantiate(root)
# simulate until program terminates
exit_event = m5.simulate()
if options.maxtick:
exit_event = m5.simulate(options.maxtick)
else:
exit_event = m5.simulate()
print 'Exiting @ cycle', m5.curTick(), 'because', exit_event.getCause()

View File

@@ -85,6 +85,7 @@ base_sources = Split('''
cpu/base.cc
cpu/cpuevent.cc
cpu/exetrace.cc
cpu/func_unit.cc
cpu/op_class.cc
cpu/pc_event.cc
cpu/quiesce_event.cc
@@ -93,8 +94,6 @@ base_sources = Split('''
cpu/simple_thread.cc
cpu/thread_state.cc
encumbered/cpu/full/fu_pool.cc
mem/bridge.cc
mem/bus.cc
mem/mem_object.cc
@@ -107,7 +106,7 @@ base_sources = Split('''
sim/eventq.cc
sim/faults.cc
sim/main.cc
python/swig/main_wrap.cc
python/swig/cc_main_wrap.cc
sim/param.cc
sim/profile.cc
sim/root.cc

View File

@@ -47,9 +47,11 @@ decode OPCODE default Unknown::unknown() {
0x23: ldt({{ Fa = Mem.df; }});
0x2a: ldl_l({{ Ra.sl = Mem.sl; }}, mem_flags = LOCKED);
0x2b: ldq_l({{ Ra.uq = Mem.uq; }}, mem_flags = LOCKED);
#ifdef USE_COPY
0x20: MiscPrefetch::copy_load({{ EA = Ra; }},
{{ fault = xc->copySrcTranslate(EA); }},
inst_flags = [IsMemRef, IsLoad, IsCopy]);
#endif
}
format LoadOrPrefetch {
@@ -69,9 +71,11 @@ decode OPCODE default Unknown::unknown() {
0x0f: stq_u({{ Mem.uq = Ra.uq; }}, {{ EA = (Rb + disp) & ~7; }});
0x26: sts({{ Mem.ul = t_to_s(Fa.uq); }});
0x27: stt({{ Mem.df = Fa; }});
#ifdef USE_COPY
0x24: MiscPrefetch::copy_store({{ EA = Rb; }},
{{ fault = xc->copy(EA); }},
inst_flags = [IsMemRef, IsStore, IsCopy]);
#endif
}
format StoreCond {

View File

@@ -115,6 +115,7 @@ baseFlags = [
'MSHR',
'Mbox',
'MemDepUnit',
'O3CPU',
'OzoneCPU',
'FE',
'IBE',

View File

@@ -92,6 +92,10 @@ env.Command('static_inst_exec_sigs.hh', models_db,
Action(gen_cpu_exec_signatures, gen_sigs_string,
varlist = ['CPU_MODELS']))
# List of suppported CPUs by the Checker. Errors out if USE_CHECKER=True
# and one of these are not being used.
CheckerSupportedCPUList = ['AlphaO3CPU', 'OzoneCPU']
#################################################################
#
# Include CPU-model-specific files based on set of models
@@ -116,7 +120,7 @@ if need_simple_base:
if 'FastCPU' in env['CPU_MODELS']:
sources += Split('fast/cpu.cc')
if 'AlphaFullCPU' in env['CPU_MODELS']:
if 'AlphaO3CPU' in env['CPU_MODELS']:
sources += Split('''
base_dyn_inst.cc
o3/2bit_local_pred.cc
@@ -144,6 +148,8 @@ if 'AlphaFullCPU' in env['CPU_MODELS']:
o3/store_set.cc
o3/tournament_pred.cc
''')
if 'CheckerCPU' in env['CPU_MODELS']:
sources += Split('checker/o3_builder.cc')
if 'OzoneSimpleCPU' in env['CPU_MODELS']:
sources += Split('''
@@ -155,6 +161,8 @@ if 'OzoneSimpleCPU' in env['CPU_MODELS']:
ozone/inst_queue.cc
ozone/rename_table.cc
''')
if 'CheckerCPU' in env['CPU_MODELS']:
sources += Split('checker/ozone_builder.cc')
if 'OzoneCPU' in env['CPU_MODELS']:
sources += Split('''
@@ -164,12 +172,19 @@ if 'OzoneCPU' in env['CPU_MODELS']:
''')
if 'CheckerCPU' in env['CPU_MODELS']:
sources += Split('''
checker/cpu.cc
checker/o3_cpu_builder.cc
''')
sources += Split('checker/cpu.cc')
checker_supports = False
for i in CheckerSupportedCPUList:
if i in env['CPU_MODELS']:
checker_supports = True
if not checker_supports:
print "Checker only supports CPU models %s, please " \
"set USE_CHECKER=False or use one of those CPU models" \
% CheckerSupportedCPUList
Exit(1)
# FullCPU sources are included from m5/SConscript since they're not
# 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

View File

@@ -71,8 +71,8 @@ my_hash_t thishash;
template <class Impl>
BaseDynInst<Impl>::BaseDynInst(ExtMachInst machInst, Addr inst_PC,
Addr pred_PC, InstSeqNum seq_num,
FullCPU *cpu)
: staticInst(machInst), traceData(NULL), cpu(cpu)/*, xc(cpu->xcBase())*/
ImplCPU *cpu)
: staticInst(machInst), traceData(NULL), cpu(cpu)
{
seqNum = seq_num;
@@ -99,39 +99,18 @@ BaseDynInst<Impl>::initVars()
memData = NULL;
effAddr = 0;
physEffAddr = 0;
storeSize = 0;
readyRegs = 0;
instResult.integer = 0;
// May want to turn this into a bit vector or something.
completed = false;
resultReady = false;
canIssue = false;
issued = false;
executed = false;
canCommit = false;
committed = false;
squashed = false;
squashedInIQ = false;
squashedInLSQ = false;
squashedInROB = false;
status.reset();
eaCalcDone = false;
memOpDone = false;
lqIdx = -1;
sqIdx = -1;
reachedCommit = false;
blockingInst = false;
recoverInst = false;
iqEntry = false;
robEntry = false;
serializeBefore = false;
serializeAfter = false;
serializeHandled = false;
// Eventually make this a parameter.
threadNumber = 0;
@@ -294,7 +273,7 @@ void
BaseDynInst<Impl>::markSrcRegReady()
{
if (++readyRegs == numSrcRegs()) {
canIssue = true;
status.set(CanIssue);
}
}
@@ -302,13 +281,9 @@ template <class Impl>
void
BaseDynInst<Impl>::markSrcRegReady(RegIndex src_idx)
{
++readyRegs;
_readySrcRegIdx[src_idx] = true;
if (readyRegs == numSrcRegs()) {
canIssue = true;
}
markSrcRegReady();
}
template <class Impl>

View File

@@ -31,6 +31,7 @@
#ifndef __CPU_BASE_DYN_INST_HH__
#define __CPU_BASE_DYN_INST_HH__
#include <bitset>
#include <list>
#include <string>
@@ -58,8 +59,8 @@ class BaseDynInst : public FastAlloc, public RefCounted
{
public:
// Typedef for the CPU.
typedef typename Impl::FullCPU FullCPU;
typedef typename FullCPU::ImplState ImplState;
typedef typename Impl::CPUType ImplCPU;
typedef typename ImplCPU::ImplState ImplState;
// Binary machine instruction type.
typedef TheISA::MachInst MachInst;
@@ -126,56 +127,34 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** The sequence number of the instruction. */
InstSeqNum seqNum;
/** Is the instruction in the IQ */
bool iqEntry;
enum Status {
IqEntry, /// Instruction is in the IQ
RobEntry, /// Instruction is in the ROB
LsqEntry, /// Instruction is in the LSQ
Completed, /// Instruction has completed
ResultReady, /// Instruction has its result
CanIssue, /// Instruction can issue and execute
Issued, /// Instruction has issued
Executed, /// Instruction has executed
CanCommit, /// Instruction can commit
AtCommit, /// Instruction has reached commit
Committed, /// Instruction has committed
Squashed, /// Instruction is squashed
SquashedInIQ, /// Instruction is squashed in the IQ
SquashedInLSQ, /// Instruction is squashed in the LSQ
SquashedInROB, /// Instruction is squashed in the ROB
RecoverInst, /// Is a recover instruction
BlockingInst, /// Is a blocking instruction
ThreadsyncWait, /// Is a thread synchronization instruction
SerializeBefore, /// Needs to serialize on
/// instructions ahead of it
SerializeAfter, /// Needs to serialize instructions behind it
SerializeHandled, /// Serialization has been handled
NumStatus
};
/** Is the instruction in the ROB */
bool robEntry;
/** Is the instruction in the LSQ */
bool lsqEntry;
/** Is the instruction completed. */
bool completed;
/** Is the instruction's result ready. */
bool resultReady;
/** Can this instruction issue. */
bool canIssue;
/** Has this instruction issued. */
bool issued;
/** Has this instruction executed (or made it through execute) yet. */
bool executed;
/** Can this instruction commit. */
bool canCommit;
/** Is this instruction committed. */
bool committed;
/** Is this instruction squashed. */
bool squashed;
/** Is this instruction squashed in the instruction queue. */
bool squashedInIQ;
/** Is this instruction squashed in the instruction queue. */
bool squashedInLSQ;
/** Is this instruction squashed in the instruction queue. */
bool squashedInROB;
/** Is this a recover instruction. */
bool recoverInst;
/** Is this a thread blocking instruction. */
bool blockingInst; /* this inst has called thread_block() */
/** Is this a thread syncrhonization instruction. */
bool threadsyncWait;
/** The status of this BaseDynInst. Several bits can be set. */
std::bitset<NumStatus> status;
/** The thread this instruction is from. */
short threadNumber;
@@ -186,8 +165,8 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** How many source registers are ready. */
unsigned readyRegs;
/** Pointer to the FullCPU object. */
FullCPU *cpu;
/** Pointer to the Impl's CPU object. */
ImplCPU *cpu;
/** Pointer to the thread state. */
ImplState *thread;
@@ -216,12 +195,6 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** The memory request flags (from translation). */
unsigned memReqFlags;
/** The size of the data to be stored. */
int storeSize;
/** The data to be stored. */
IntReg storeData;
union Result {
uint64_t integer;
float fp;
@@ -266,7 +239,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
* @param cpu Pointer to the instruction's CPU.
*/
BaseDynInst(ExtMachInst inst, Addr PC, Addr pred_PC, InstSeqNum seq_num,
FullCPU *cpu);
ImplCPU *cpu);
/** BaseDynInst constructor given a StaticInst pointer.
* @param _staticInst The StaticInst for this BaseDynInst.
@@ -338,9 +311,9 @@ class BaseDynInst : public FastAlloc, public RefCounted
bool isThreadSync() const { return staticInst->isThreadSync(); }
bool isSerializing() const { return staticInst->isSerializing(); }
bool isSerializeBefore() const
{ return staticInst->isSerializeBefore() || serializeBefore; }
{ return staticInst->isSerializeBefore() || status[SerializeBefore]; }
bool isSerializeAfter() const
{ return staticInst->isSerializeAfter() || serializeAfter; }
{ return staticInst->isSerializeAfter() || status[SerializeAfter]; }
bool isMemBarrier() const { return staticInst->isMemBarrier(); }
bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
@@ -349,41 +322,32 @@ class BaseDynInst : public FastAlloc, public RefCounted
bool isUnverifiable() const { return staticInst->isUnverifiable(); }
/** Temporarily sets this instruction as a serialize before instruction. */
void setSerializeBefore() { serializeBefore = true; }
void setSerializeBefore() { status.set(SerializeBefore); }
/** Clears the serializeBefore part of this instruction. */
void clearSerializeBefore() { serializeBefore = false; }
void clearSerializeBefore() { status.reset(SerializeBefore); }
/** Checks if this serializeBefore is only temporarily set. */
bool isTempSerializeBefore() { return serializeBefore; }
/** Tracks if instruction has been externally set as serializeBefore. */
bool serializeBefore;
bool isTempSerializeBefore() { return status[SerializeBefore]; }
/** Temporarily sets this instruction as a serialize after instruction. */
void setSerializeAfter() { serializeAfter = true; }
void setSerializeAfter() { status.set(SerializeAfter); }
/** Clears the serializeAfter part of this instruction.*/
void clearSerializeAfter() { serializeAfter = false; }
void clearSerializeAfter() { status.reset(SerializeAfter); }
/** Checks if this serializeAfter is only temporarily set. */
bool isTempSerializeAfter() { return serializeAfter; }
bool isTempSerializeAfter() { return status[SerializeAfter]; }
/** Tracks if instruction has been externally set as serializeAfter. */
bool serializeAfter;
/** Sets the serialization part of this instruction as handled. */
void setSerializeHandled() { status.set(SerializeHandled); }
/** Checks if the serialization part of this instruction has been
* handled. This does not apply to the temporary serializing
* state; it only applies to this instruction's own permanent
* serializing state.
*/
bool isSerializeHandled() { return serializeHandled; }
/** Sets the serialization part of this instruction as handled. */
void setSerializeHandled() { serializeHandled = true; }
/** Whether or not the serialization of this instruction has been handled. */
bool serializeHandled;
bool isSerializeHandled() { return status[SerializeHandled]; }
/** Returns the opclass of this instruction. */
OpClass opClass() const { return staticInst->opClass(); }
@@ -465,106 +429,112 @@ class BaseDynInst : public FastAlloc, public RefCounted
}
/** Sets this instruction as completed. */
void setCompleted() { completed = true; }
void setCompleted() { status.set(Completed); }
/** Returns whether or not this instruction is completed. */
bool isCompleted() const { return completed; }
bool isCompleted() const { return status[Completed]; }
void setResultReady() { resultReady = true; }
/** Marks the result as ready. */
void setResultReady() { status.set(ResultReady); }
bool isResultReady() const { return resultReady; }
/** Returns whether or not the result is ready. */
bool isResultReady() const { return status[ResultReady]; }
/** Sets this instruction as ready to issue. */
void setCanIssue() { canIssue = true; }
void setCanIssue() { status.set(CanIssue); }
/** Returns whether or not this instruction is ready to issue. */
bool readyToIssue() const { return canIssue; }
bool readyToIssue() const { return status[CanIssue]; }
/** Sets this instruction as issued from the IQ. */
void setIssued() { issued = true; }
void setIssued() { status.set(Issued); }
/** Returns whether or not this instruction has issued. */
bool isIssued() const { return issued; }
bool isIssued() const { return status[Issued]; }
/** Sets this instruction as executed. */
void setExecuted() { executed = true; }
void setExecuted() { status.set(Executed); }
/** Returns whether or not this instruction has executed. */
bool isExecuted() const { return executed; }
bool isExecuted() const { return status[Executed]; }
/** Sets this instruction as ready to commit. */
void setCanCommit() { canCommit = true; }
void setCanCommit() { status.set(CanCommit); }
/** Clears this instruction as being ready to commit. */
void clearCanCommit() { canCommit = false; }
void clearCanCommit() { status.reset(CanCommit); }
/** Returns whether or not this instruction is ready to commit. */
bool readyToCommit() const { return canCommit; }
bool readyToCommit() const { return status[CanCommit]; }
void setAtCommit() { status.set(AtCommit); }
bool isAtCommit() { return status[AtCommit]; }
/** Sets this instruction as committed. */
void setCommitted() { committed = true; }
void setCommitted() { status.set(Committed); }
/** Returns whether or not this instruction is committed. */
bool isCommitted() const { return committed; }
bool isCommitted() const { return status[Committed]; }
/** Sets this instruction as squashed. */
void setSquashed() { squashed = true; }
void setSquashed() { status.set(Squashed); }
/** Returns whether or not this instruction is squashed. */
bool isSquashed() const { return squashed; }
bool isSquashed() const { return status[Squashed]; }
//Instruction Queue Entry
//-----------------------
/** Sets this instruction as a entry the IQ. */
void setInIQ() { iqEntry = true; }
void setInIQ() { status.set(IqEntry); }
/** Sets this instruction as a entry the IQ. */
void removeInIQ() { iqEntry = false; }
/** Sets this instruction as squashed in the IQ. */
void setSquashedInIQ() { squashedInIQ = true; squashed = true;}
/** Returns whether or not this instruction is squashed in the IQ. */
bool isSquashedInIQ() const { return squashedInIQ; }
void clearInIQ() { status.reset(IqEntry); }
/** Returns whether or not this instruction has issued. */
bool isInIQ() const { return iqEntry; }
bool isInIQ() const { return status[IqEntry]; }
/** Sets this instruction as squashed in the IQ. */
void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);}
/** Returns whether or not this instruction is squashed in the IQ. */
bool isSquashedInIQ() const { return status[SquashedInIQ]; }
//Load / Store Queue Functions
//-----------------------
/** Sets this instruction as a entry the LSQ. */
void setInLSQ() { lsqEntry = true; }
void setInLSQ() { status.set(LsqEntry); }
/** Sets this instruction as a entry the LSQ. */
void removeInLSQ() { lsqEntry = false; }
/** Sets this instruction as squashed in the LSQ. */
void setSquashedInLSQ() { squashedInLSQ = true;}
/** Returns whether or not this instruction is squashed in the LSQ. */
bool isSquashedInLSQ() const { return squashedInLSQ; }
void removeInLSQ() { status.reset(LsqEntry); }
/** Returns whether or not this instruction is in the LSQ. */
bool isInLSQ() const { return lsqEntry; }
bool isInLSQ() const { return status[LsqEntry]; }
/** Sets this instruction as squashed in the LSQ. */
void setSquashedInLSQ() { status.set(SquashedInLSQ);}
/** Returns whether or not this instruction is squashed in the LSQ. */
bool isSquashedInLSQ() const { return status[SquashedInLSQ]; }
//Reorder Buffer Functions
//-----------------------
/** Sets this instruction as a entry the ROB. */
void setInROB() { robEntry = true; }
void setInROB() { status.set(RobEntry); }
/** Sets this instruction as a entry the ROB. */
void removeInROB() { robEntry = false; }
/** Sets this instruction as squashed in the ROB. */
void setSquashedInROB() { squashedInROB = true; }
/** Returns whether or not this instruction is squashed in the ROB. */
bool isSquashedInROB() const { return squashedInROB; }
void clearInROB() { status.reset(RobEntry); }
/** Returns whether or not this instruction is in the ROB. */
bool isInROB() const { return robEntry; }
bool isInROB() const { return status[RobEntry]; }
/** Sets this instruction as squashed in the ROB. */
void setSquashedInROB() { status.set(SquashedInROB); }
/** Returns whether or not this instruction is squashed in the ROB. */
bool isSquashedInROB() const { return status[SquashedInROB]; }
/** Read the PC of this instruction. */
const Addr readPC() const { return PC; }
@@ -581,10 +551,10 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Sets the thread id. */
void setTid(unsigned tid) { threadNumber = tid; }
/** Sets the pointer to the thread state. */
void setThreadState(ImplState *state) { thread = state; }
/** Returns the thread context.
*/
/** Returns the thread context. */
ThreadContext *tcBase() { return thread->getTC(); }
private:
@@ -621,8 +591,6 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Store queue index. */
int16_t sqIdx;
bool reachedCommit;
/** Iterator pointing to this BaseDynInst in the list of all insts. */
ListIt instListIt;

View File

@@ -78,6 +78,7 @@ CheckerCPU::CheckerCPU(Params *p)
changedPC = willChangePC = changedNextPC = false;
exitOnError = p->exitOnError;
warnOnlyOnLoadError = p->warnOnlyOnLoadError;
#if FULL_SYSTEM
itb = p->itb;
dtb = p->dtb;
@@ -409,9 +410,17 @@ CheckerCPU::checkFlags(Request *req)
}
}
void
CheckerCPU::dumpAndExit()
{
warn("%lli: Checker PC:%#x, next PC:%#x",
curTick, thread->readPC(), thread->readNextPC());
panic("Checker found an error!");
}
template <class DynInstPtr>
void
Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
{
DynInstPtr inst;
@@ -485,7 +494,7 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
warn("%lli: Changed PC does not match expected PC, "
"changed: %#x, expected: %#x",
curTick, thread->readPC(), newPC);
handleError();
CheckerCPU::handleError();
}
willChangePC = false;
}
@@ -524,7 +533,7 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
// possible that its ITB entry was kicked out.
warn("%lli: Instruction PC %#x was not found in the ITB!",
curTick, thread->readPC());
handleError();
handleError(inst);
// go to the next instruction
thread->setPC(thread->readNextPC());
@@ -676,7 +685,7 @@ Checker<DynInstPtr>::validateInst(DynInstPtr &inst)
warn("%lli: Changed PCs recently, may not be an error",
curTick);
} else {
handleError();
handleError(inst);
}
}
@@ -686,7 +695,7 @@ Checker<DynInstPtr>::validateInst(DynInstPtr &inst)
warn("%lli: Binary instructions do not match! Inst: %#x, "
"checker: %#x",
curTick, mi, machInst);
handleError();
handleError(inst);
}
}
@@ -694,25 +703,33 @@ template <class DynInstPtr>
void
Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
{
bool result_mismatch = false;
if (inst->numDestRegs()) {
// @todo: Support more destination registers.
if (inst->isUnverifiable()) {
// Unverifiable instructions assume they were executed
// properly by the CPU. Grab the result from the
// instruction and write it to the register.
RegIndex idx = inst->destRegIdx(0);
if (idx < TheISA::FP_Base_DepTag) {
thread->setIntReg(idx, inst->readIntResult());
} else if (idx < TheISA::Fpcr_DepTag) {
thread->setFloatRegBits(idx, inst->readIntResult());
} else {
thread->setMiscReg(idx, inst->readIntResult());
}
copyResult(inst);
} else if (result.integer != inst->readIntResult()) {
warn("%lli: Instruction results do not match! (Values may not "
"actually be integers) Inst: %#x, checker: %#x",
curTick, inst->readIntResult(), result.integer);
handleError();
result_mismatch = true;
}
}
if (result_mismatch) {
warn("%lli: Instruction results do not match! (Values may not "
"actually be integers) Inst: %#x, checker: %#x",
curTick, inst->readIntResult(), result.integer);
// It's useful to verify load values from memory, but in MP
// systems the value obtained at execute may be different than
// the value obtained at completion. Similarly DMA can
// present the same problem on even UP systems. Thus there is
// the option to only warn on loads having a result error.
if (inst->isLoad() && warnOnlyOnLoadError) {
copyResult(inst);
} else {
handleError(inst);
}
}
@@ -720,7 +737,7 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
warn("%lli: Instruction next PCs do not match! Inst: %#x, "
"checker: %#x",
curTick, inst->readNextPC(), thread->readNextPC());
handleError();
handleError(inst);
}
// Checking side effect registers can be difficult if they are not
@@ -739,7 +756,7 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
curTick, misc_reg_idx,
inst->tcBase()->readMiscReg(misc_reg_idx),
thread->readMiscReg(misc_reg_idx));
handleError();
handleError(inst);
}
}
}
@@ -750,6 +767,36 @@ Checker<DynInstPtr>::validateState()
{
}
template <class DynInstPtr>
void
Checker<DynInstPtr>::copyResult(DynInstPtr &inst)
{
RegIndex idx = inst->destRegIdx(0);
if (idx < TheISA::FP_Base_DepTag) {
thread->setIntReg(idx, inst->readIntResult());
} else if (idx < TheISA::Fpcr_DepTag) {
thread->setFloatRegBits(idx, inst->readIntResult());
} else {
thread->setMiscReg(idx, inst->readIntResult());
}
}
template <class DynInstPtr>
void
Checker<DynInstPtr>::dumpAndExit(DynInstPtr &inst)
{
cprintf("Error detected, instruction information:\n");
cprintf("PC:%#x, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n"
"Completed:%i\n",
inst->readPC(),
inst->readNextPC(),
inst->seqNum,
inst->threadNumber,
inst->isCompleted());
inst->dump();
CheckerCPU::dumpAndExit();
}
template <class DynInstPtr>
void
Checker<DynInstPtr>::dumpInsts()
@@ -782,6 +829,6 @@ Checker<DynInstPtr>::dumpInsts()
//template
//class Checker<RefCountingPtr<OzoneDynInst<OzoneImpl> > >;
// Manually instantiate checker
template
class Checker<RefCountingPtr<AlphaDynInst<AlphaSimpleImpl> > >;

View File

@@ -103,6 +103,7 @@ class CheckerCPU : public BaseCPU
Process *process;
#endif
bool exitOnError;
bool warnOnlyOnLoadError;
};
public:
@@ -335,10 +336,13 @@ class CheckerCPU : public BaseCPU
void handleError()
{
if (exitOnError)
panic("Checker found error!");
dumpAndExit();
}
bool checkFlags(Request *req);
void dumpAndExit();
ThreadContext *tcBase() { return tc; }
SimpleThread *threadBase() { return thread; }
@@ -351,6 +355,7 @@ class CheckerCPU : public BaseCPU
uint64_t newPC;
bool changedNextPC;
bool exitOnError;
bool warnOnlyOnLoadError;
InstSeqNum youngestSN;
};
@@ -372,12 +377,23 @@ class Checker : public CheckerCPU
void switchOut(Sampler *s);
void takeOverFrom(BaseCPU *oldCPU);
void tick(DynInstPtr &inst);
void verify(DynInstPtr &inst);
void validateInst(DynInstPtr &inst);
void validateExecution(DynInstPtr &inst);
void validateState();
void copyResult(DynInstPtr &inst);
private:
void handleError(DynInstPtr &inst)
{
if (exitOnError)
dumpAndExit(inst);
}
void dumpAndExit(DynInstPtr &inst);
std::list<DynInstPtr> instList;
typedef typename std::list<DynInstPtr>::iterator InstListIt;
void dumpInsts();

View File

@@ -75,6 +75,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<bool> defer_registration;
Param<bool> exitOnError;
Param<bool> warnOnlyOnLoadError;
Param<bool> function_trace;
Param<Tick> function_trace_start;
@@ -105,6 +106,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(O3Checker)
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(exitOnError, "exit on error"),
INIT_PARAM_DFLT(warnOnlyOnLoadError, "warn, but don't exit, if a load "
"result errors", false),
INIT_PARAM(function_trace, "Enable function trace"),
INIT_PARAM(function_trace_start, "Cycle to start function trace")
@@ -121,6 +124,7 @@ CREATE_SIM_OBJECT(O3Checker)
params->max_loads_any_thread = 0;
params->max_loads_all_threads = 0;
params->exitOnError = exitOnError;
params->warnOnlyOnLoadError = warnOnlyOnLoadError;
params->deferRegistration = defer_registration;
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;

View File

@@ -77,6 +77,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
Param<bool> defer_registration;
Param<bool> exitOnError;
Param<bool> warnOnlyOnLoadError;
Param<bool> function_trace;
Param<Tick> function_trace_start;
@@ -110,6 +111,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker)
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(exitOnError, "exit on error"),
INIT_PARAM_DFLT(warnOnlyOnLoadError, "warn, but don't exit, if a load "
"result errors", false),
INIT_PARAM(function_trace, "Enable function trace"),
INIT_PARAM(function_trace_start, "Cycle to start function trace")
@@ -126,6 +129,7 @@ CREATE_SIM_OBJECT(OzoneChecker)
params->max_loads_any_thread = 0;
params->max_loads_all_threads = 0;
params->exitOnError = exitOnError;
params->warnOnlyOnLoadError = warnOnlyOnLoadError;
params->deferRegistration = defer_registration;
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;

View File

@@ -67,7 +67,7 @@ CpuModel('TimingSimpleCPU', 'timing_simple_cpu_exec.cc',
CpuModel('FullCPU', 'full_cpu_exec.cc',
'#include "encumbered/cpu/full/dyn_inst.hh"',
{ 'CPU_exec_context': 'DynInst' })
CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc',
CpuModel('AlphaO3CPU', 'alpha_o3_exec.cc',
'#include "cpu/o3/alpha_dyn_inst.hh"',
{ 'CPU_exec_context': 'AlphaDynInst<AlphaSimpleImpl>' })
CpuModel('OzoneSimpleCPU', 'ozone_simple_exec.cc',

View File

@@ -36,7 +36,7 @@
class ThreadContext;
/** This class creates a global list of events than need a pointer to an
/** This class creates a global list of events that need a pointer to a
* thread context. When a switchover takes place the events can be migrated
* to the new thread context, otherwise you could have a wake timer interrupt
* go off on a switched out cpu or other unfortunate events. This object MUST be

161
src/cpu/exec_context.hh Normal file
View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
*/
#error "Cannot include this file"
/**
* The ExecContext is not a usable class. It is simply here for
* documentation purposes. It shows the interface that is used by the
* ISA to access and change CPU state.
*/
class ExecContext {
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
// register index, to simplify the implementation of register
// renaming. We find the architectural register index by indexing
// into the instruction's own operand index table. Note that a
// raw pointer to the StaticInst is provided instead of a
// ref-counted StaticInstPtr to reduce overhead. This is fine as
// long as these methods don't copy the pointer into any long-term
// storage (which is pretty hard to imagine they would have reason
// to do).
/** Reads an integer register. */
uint64_t readIntReg(const StaticInst *si, int idx);
/** Reads a floating point register of a specific width. */
FloatReg readFloatReg(const StaticInst *si, int idx, int width);
/** Reads a floating point register of single register width. */
FloatReg readFloatReg(const StaticInst *si, int idx);
/** Reads a floating point register of a specific width in its
* binary format, instead of by value. */
FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width);
/** Reads a floating point register in its binary format, instead
* of by value. */
FloatRegBits readFloatRegBits(const StaticInst *si, int idx);
/** Sets an integer register to a value. */
void setIntReg(const StaticInst *si, int idx, uint64_t val);
/** Sets a floating point register of a specific width to a value. */
void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width);
/** Sets a floating point register of single width to a value. */
void setFloatReg(const StaticInst *si, int idx, FloatReg val);
/** Sets the bits of a floating point register of a specific width
* to a binary value. */
void setFloatRegBits(const StaticInst *si, int idx,
FloatRegBits val, int width);
/** Sets the bits of a floating point register of single width
* to a binary value. */
void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val);
/** Reads the PC. */
uint64_t readPC();
/** Reads the NextPC. */
uint64_t readNextPC();
/** Reads the Next-NextPC. Only for architectures like SPARC or MIPS. */
uint64_t readNextNPC();
/** Sets the PC. */
void setPC(uint64_t val);
/** Sets the NextPC. */
void setNextPC(uint64_t val);
/** Sets the Next-NextPC. Only for architectures like SPARC or MIPS. */
void setNextNPC(uint64_t val);
/** Reads a miscellaneous register. */
MiscReg readMiscReg(int misc_reg);
/** Reads a miscellaneous register, handling any architectural
* side effects due to reading that register. */
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault);
/** Sets a miscellaneous register. */
Fault setMiscReg(int misc_reg, const MiscReg &val);
/** Sets a miscellaneous register, handling any architectural
* side effects due to writing that register. */
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
/** Records the effective address of the instruction. Only valid
* for memory ops. */
void setEA(Addr EA);
/** Returns the effective address of the instruction. Only valid
* for memory ops. */
Addr getEA();
/** Returns a pointer to the ThreadContext. */
ThreadContext *tcBase();
/** Reads an address, creating a memory request with the given
* flags. Stores result of read in data. */
template <class T>
Fault read(Addr addr, T &data, unsigned flags);
/** Writes to an address, creating a memory request with the given
* flags. Writes data to memory. For store conditionals, returns
* the result of the store in res. */
template <class T>
Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
/** Prefetches an address, creating a memory request with the
* given flags. */
void prefetch(Addr addr, unsigned flags);
/** Hints to the memory system that an address will be written to
* soon, with the given size. Creates a memory request with the
* given flags. */
void writeHint(Addr addr, int size, unsigned flags);
#if FULL_SYSTEM
/** Somewhat Alpha-specific function that handles returning from
* an error or interrupt. */
Fault hwrei();
/** Reads the interrupt flags. */
int readIntrFlag();
/** Sets the interrupt flags to a value. */
void setIntrFlag(int val);
/**
* Check for special simulator handling of specific PAL calls. If
* return value is false, actual PAL call will be suppressed.
*/
bool simPalCheck(int palFunc);
#else
/** Executes a syscall specified by the callnum. */
void syscall(int64_t callnum);
#endif
};

171
src/cpu/func_unit.cc Normal file
View File

@@ -0,0 +1,171 @@
/*
* Copyright (c) 2002-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Raasch
*/
#include <sstream>
#include "base/misc.hh"
#include "cpu/func_unit.hh"
#include "sim/builder.hh"
using namespace std;
////////////////////////////////////////////////////////////////////////////
//
// The funciton unit
//
FuncUnit::FuncUnit()
{
capabilityList.reset();
}
// Copy constructor
FuncUnit::FuncUnit(const FuncUnit &fu)
{
for (int i = 0; i < Num_OpClasses; ++i) {
opLatencies[i] = fu.opLatencies[i];
issueLatencies[i] = fu.issueLatencies[i];
}
capabilityList = fu.capabilityList;
}
void
FuncUnit::addCapability(OpClass cap, unsigned oplat, unsigned issuelat)
{
if (issuelat == 0 || oplat == 0)
panic("FuncUnit: you don't really want a zero-cycle latency do you?");
capabilityList.set(cap);
opLatencies[cap] = oplat;
issueLatencies[cap] = issuelat;
}
bool
FuncUnit::provides(OpClass capability)
{
return capabilityList[capability];
}
bitset<Num_OpClasses>
FuncUnit::capabilities()
{
return capabilityList;
}
unsigned &
FuncUnit::opLatency(OpClass cap)
{
return opLatencies[cap];
}
unsigned
FuncUnit::issueLatency(OpClass capability)
{
return issueLatencies[capability];
}
////////////////////////////////////////////////////////////////////////////
//
// The SimObjects we use to get the FU information into the simulator
//
////////////////////////////////////////////////////////////////////////////
//
// We use 2 objects to specify this data in the INI file:
// (1) OpDesc - Describes the operation class & latencies
// (multiple OpDesc objects can refer to the same
// operation classes)
// (2) FUDesc - Describes the operations available in the unit &
// the number of these units
//
//
//
// The operation-class description object
//
BEGIN_DECLARE_SIM_OBJECT_PARAMS(OpDesc)
SimpleEnumParam<OpClass> opClass;
Param<unsigned> opLat;
Param<unsigned> issueLat;
END_DECLARE_SIM_OBJECT_PARAMS(OpDesc)
BEGIN_INIT_SIM_OBJECT_PARAMS(OpDesc)
INIT_ENUM_PARAM(opClass, "type of operation", opClassStrings),
INIT_PARAM(opLat, "cycles until result is available"),
INIT_PARAM(issueLat, "cycles until another can be issued")
END_INIT_SIM_OBJECT_PARAMS(OpDesc)
CREATE_SIM_OBJECT(OpDesc)
{
return new OpDesc(getInstanceName(), opClass, opLat, issueLat);
}
REGISTER_SIM_OBJECT("OpDesc", OpDesc)
//
// The FuDesc object
//
BEGIN_DECLARE_SIM_OBJECT_PARAMS(FUDesc)
SimObjectVectorParam<OpDesc *> opList;
Param<unsigned> count;
END_DECLARE_SIM_OBJECT_PARAMS(FUDesc)
BEGIN_INIT_SIM_OBJECT_PARAMS(FUDesc)
INIT_PARAM(opList, "list of operation classes for this FU type"),
INIT_PARAM(count, "number of these FU's available")
END_INIT_SIM_OBJECT_PARAMS(FUDesc)
CREATE_SIM_OBJECT(FUDesc)
{
return new FUDesc(getInstanceName(), opList, count);
}
REGISTER_SIM_OBJECT("FUDesc", FUDesc)

101
src/cpu/func_unit.hh Normal file
View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2002-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Raasch
*/
#ifndef __CPU_FUNC_UNIT_HH__
#define __CPU_FUNC_UNIT_HH__
#include <bitset>
#include <string>
#include <vector>
#include "cpu/op_class.hh"
#include "sim/sim_object.hh"
////////////////////////////////////////////////////////////////////////////
//
// Structures used ONLY during the initialization phase...
//
//
//
struct OpDesc : public SimObject
{
OpClass opClass;
unsigned opLat;
unsigned issueLat;
OpDesc(std::string name, OpClass c, unsigned o, unsigned i)
: SimObject(name), opClass(c), opLat(o), issueLat(i) {};
};
struct FUDesc : public SimObject
{
std::vector<OpDesc *> opDescList;
unsigned number;
FUDesc(std::string name, std::vector<OpDesc *> l, unsigned n)
: SimObject(name), opDescList(l), number(n) {};
};
typedef std::vector<OpDesc *>::iterator OPDDiterator;
typedef std::vector<FUDesc *>::iterator FUDDiterator;
////////////////////////////////////////////////////////////////////////////
//
// The actual FU object
//
//
//
class FuncUnit
{
private:
unsigned opLatencies[Num_OpClasses];
unsigned issueLatencies[Num_OpClasses];
std::bitset<Num_OpClasses> capabilityList;
public:
FuncUnit();
FuncUnit(const FuncUnit &fu);
std::string name;
void addCapability(OpClass cap, unsigned oplat, unsigned issuelat);
bool provides(OpClass capability);
std::bitset<Num_OpClasses> capabilities();
unsigned &opLatency(OpClass capability);
unsigned issueLatency(OpClass capability);
};
#endif // __FU_POOL_HH__

View File

@@ -32,7 +32,7 @@
#include "cpu/o3/alpha_cpu_impl.hh"
#include "cpu/o3/alpha_dyn_inst.hh"
// Force instantiation of AlphaFullCPU for all the implemntations that are
// Force instantiation of AlphaO3CPU for all the implemntations that are
// needed. Consider merging this and alpha_dyn_inst.cc, and maybe all
// classes that depend on a certain impl, into one file (alpha_impl.cc?).
template class AlphaFullCPU<AlphaSimpleImpl>;
template class AlphaO3CPU<AlphaSimpleImpl>;

View File

@@ -44,7 +44,7 @@ namespace Kernel {
class TranslatingPort;
/**
* AlphaFullCPU class. Derives from the FullO3CPU class, and
* AlphaO3CPU class. Derives from the FullO3CPU class, and
* implements all ISA and implementation specific functions of the
* CPU. This is the CPU class that is used for the SimObjects, and is
* what is given to the DynInsts. Most of its state exists in the
@@ -52,7 +52,7 @@ class TranslatingPort;
* functionality.
*/
template <class Impl>
class AlphaFullCPU : public FullO3CPU<Impl>
class AlphaO3CPU : public FullO3CPU<Impl>
{
protected:
typedef TheISA::IntReg IntReg;
@@ -67,17 +67,17 @@ class AlphaFullCPU : public FullO3CPU<Impl>
typedef O3ThreadState<Impl> Thread;
typedef typename Impl::Params Params;
/** Constructs an AlphaFullCPU with the given parameters. */
AlphaFullCPU(Params *params);
/** Constructs an AlphaO3CPU with the given parameters. */
AlphaO3CPU(Params *params);
/**
* Derived ThreadContext class for use with the AlphaFullCPU. It
* Derived ThreadContext class for use with the AlphaO3CPU. It
* provides the interface for any external objects to access a
* single thread's state and some general CPU state. Any time
* external objects try to update state through this interface,
* the CPU will create an event to squash all in-flight
* instructions in order to ensure state is maintained correctly.
* It must be defined specifically for the AlphaFullCPU because
* It must be defined specifically for the AlphaO3CPU because
* not all architectural state is located within the O3ThreadState
* (such as the commit PC, and registers), and specific actions
* must be taken when using this interface (such as squashing all
@@ -87,7 +87,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
{
public:
/** Pointer to the CPU. */
AlphaFullCPU<Impl> *cpu;
AlphaO3CPU<Impl> *cpu;
/** Pointer to the thread state that this TC corrseponds to. */
O3ThreadState<Impl> *thread;

View File

@@ -37,15 +37,15 @@
#include "cpu/o3/fu_pool.hh"
#include "sim/builder.hh"
class DerivAlphaFullCPU : public AlphaFullCPU<AlphaSimpleImpl>
class DerivAlphaO3CPU : public AlphaO3CPU<AlphaSimpleImpl>
{
public:
DerivAlphaFullCPU(AlphaSimpleParams *p)
: AlphaFullCPU<AlphaSimpleImpl>(p)
DerivAlphaO3CPU(AlphaSimpleParams *p)
: AlphaO3CPU<AlphaSimpleImpl>(p)
{ }
};
BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivAlphaO3CPU)
Param<int> clock;
Param<int> numThreads;
@@ -144,9 +144,9 @@ Param<bool> defer_registration;
Param<bool> function_trace;
Param<Tick> function_trace_start;
END_DECLARE_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
END_DECLARE_SIM_OBJECT_PARAMS(DerivAlphaO3CPU)
BEGIN_INIT_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
BEGIN_INIT_SIM_OBJECT_PARAMS(DerivAlphaO3CPU)
INIT_PARAM(clock, "clock speed"),
INIT_PARAM(numThreads, "number of HW thread contexts"),
@@ -261,11 +261,11 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
INIT_PARAM(function_trace, "Enable function trace"),
INIT_PARAM(function_trace_start, "Cycle to start function trace")
END_INIT_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
END_INIT_SIM_OBJECT_PARAMS(DerivAlphaO3CPU)
CREATE_SIM_OBJECT(DerivAlphaFullCPU)
CREATE_SIM_OBJECT(DerivAlphaO3CPU)
{
DerivAlphaFullCPU *cpu;
DerivAlphaO3CPU *cpu;
#if FULL_SYSTEM
// Full-system only supports a single thread for the moment.
@@ -386,10 +386,10 @@ CREATE_SIM_OBJECT(DerivAlphaFullCPU)
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;
cpu = new DerivAlphaFullCPU(params);
cpu = new DerivAlphaO3CPU(params);
return cpu;
}
REGISTER_SIM_OBJECT("DerivAlphaFullCPU", DerivAlphaFullCPU)
REGISTER_SIM_OBJECT("DerivAlphaO3CPU", DerivAlphaO3CPU)

View File

@@ -28,6 +28,8 @@
* Authors: Kevin Lim
*/
#include "config/use_checker.hh"
#include "arch/alpha/faults.hh"
#include "base/cprintf.hh"
#include "base/statistics.hh"
@@ -53,14 +55,14 @@
using namespace TheISA;
template <class Impl>
AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
AlphaO3CPU<Impl>::AlphaO3CPU(Params *params)
#if FULL_SYSTEM
: FullO3CPU<Impl>(params), itb(params->itb), dtb(params->dtb)
#else
: FullO3CPU<Impl>(params)
#endif
{
DPRINTF(FullCPU, "AlphaFullCPU: Creating AlphaFullCPU object.\n");
DPRINTF(O3CPU, "Creating AlphaO3CPU object.\n");
// Setup any thread state.
this->thread.resize(this->numThreads);
@@ -73,7 +75,7 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
this->thread[i]->setStatus(ThreadContext::Suspended);
#else
if (i < params->workload.size()) {
DPRINTF(FullCPU, "FullCPU: Workload[%i] process is %#x",
DPRINTF(O3CPU, "Workload[%i] process is %#x",
i, this->thread[i]);
this->thread[i] = new Thread(this, i, params->workload[i],
i, params->mem);
@@ -110,14 +112,16 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
// Setup the TC that will serve as the interface to the threads/CPU.
AlphaTC *alpha_tc = new AlphaTC;
tc = alpha_tc;
// If we're using a checker, then the TC should be the
// CheckerThreadContext.
#if USE_CHECKER
if (params->checker) {
tc = new CheckerThreadContext<AlphaTC>(
alpha_tc, this->checker);
} else {
tc = alpha_tc;
}
#endif
alpha_tc->cpu = this;
alpha_tc->thread = this->thread[i];
@@ -172,7 +176,7 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
template <class Impl>
void
AlphaFullCPU<Impl>::regStats()
AlphaO3CPU<Impl>::regStats()
{
// Register stats for everything that has stats.
this->fullCPURegStats();
@@ -186,7 +190,7 @@ AlphaFullCPU<Impl>::regStats()
#if FULL_SYSTEM
template <class Impl>
VirtualPort *
AlphaFullCPU<Impl>::AlphaTC::getVirtPort(ThreadContext *src_tc)
AlphaO3CPU<Impl>::AlphaTC::getVirtPort(ThreadContext *src_tc)
{
if (!src_tc)
return thread->getVirtPort();
@@ -203,7 +207,7 @@ AlphaFullCPU<Impl>::AlphaTC::getVirtPort(ThreadContext *src_tc)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::dumpFuncProfile()
AlphaO3CPU<Impl>::AlphaTC::dumpFuncProfile()
{
// Currently not supported
}
@@ -211,7 +215,7 @@ AlphaFullCPU<Impl>::AlphaTC::dumpFuncProfile()
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::takeOverFrom(ThreadContext *old_context)
AlphaO3CPU<Impl>::AlphaTC::takeOverFrom(ThreadContext *old_context)
{
// some things should already be set up
#if FULL_SYSTEM
@@ -253,7 +257,7 @@ AlphaFullCPU<Impl>::AlphaTC::takeOverFrom(ThreadContext *old_context)
#if FULL_SYSTEM
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::delVirtPort(VirtualPort *vp)
AlphaO3CPU<Impl>::AlphaTC::delVirtPort(VirtualPort *vp)
{
delete vp->getPeer();
delete vp;
@@ -262,9 +266,9 @@ AlphaFullCPU<Impl>::AlphaTC::delVirtPort(VirtualPort *vp)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::activate(int delay)
AlphaO3CPU<Impl>::AlphaTC::activate(int delay)
{
DPRINTF(FullCPU, "Calling activate on AlphaTC\n");
DPRINTF(O3CPU, "Calling activate on AlphaTC\n");
if (thread->status() == ThreadContext::Active)
return;
@@ -286,9 +290,9 @@ AlphaFullCPU<Impl>::AlphaTC::activate(int delay)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::suspend()
AlphaO3CPU<Impl>::AlphaTC::suspend()
{
DPRINTF(FullCPU, "Calling suspend on AlphaTC\n");
DPRINTF(O3CPU, "Calling suspend on AlphaTC\n");
if (thread->status() == ThreadContext::Suspended)
return;
@@ -312,9 +316,9 @@ AlphaFullCPU<Impl>::AlphaTC::suspend()
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::deallocate()
AlphaO3CPU<Impl>::AlphaTC::deallocate()
{
DPRINTF(FullCPU, "Calling deallocate on AlphaTC\n");
DPRINTF(O3CPU, "Calling deallocate on AlphaTC\n");
if (thread->status() == ThreadContext::Unallocated)
return;
@@ -325,9 +329,9 @@ AlphaFullCPU<Impl>::AlphaTC::deallocate()
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::halt()
AlphaO3CPU<Impl>::AlphaTC::halt()
{
DPRINTF(FullCPU, "Calling halt on AlphaTC\n");
DPRINTF(O3CPU, "Calling halt on AlphaTC\n");
if (thread->status() == ThreadContext::Halted)
return;
@@ -338,7 +342,7 @@ AlphaFullCPU<Impl>::AlphaTC::halt()
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::regStats(const std::string &name)
AlphaO3CPU<Impl>::AlphaTC::regStats(const std::string &name)
{
#if FULL_SYSTEM
thread->kernelStats = new Kernel::Statistics(cpu->system);
@@ -348,7 +352,7 @@ AlphaFullCPU<Impl>::AlphaTC::regStats(const std::string &name)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::serialize(std::ostream &os)
AlphaO3CPU<Impl>::AlphaTC::serialize(std::ostream &os)
{
#if FULL_SYSTEM
if (thread->kernelStats)
@@ -359,7 +363,7 @@ AlphaFullCPU<Impl>::AlphaTC::serialize(std::ostream &os)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::unserialize(Checkpoint *cp, const std::string &section)
AlphaO3CPU<Impl>::AlphaTC::unserialize(Checkpoint *cp, const std::string &section)
{
#if FULL_SYSTEM
if (thread->kernelStats)
@@ -371,46 +375,46 @@ AlphaFullCPU<Impl>::AlphaTC::unserialize(Checkpoint *cp, const std::string &sect
#if FULL_SYSTEM
template <class Impl>
EndQuiesceEvent *
AlphaFullCPU<Impl>::AlphaTC::getQuiesceEvent()
AlphaO3CPU<Impl>::AlphaTC::getQuiesceEvent()
{
return thread->quiesceEvent;
}
template <class Impl>
Tick
AlphaFullCPU<Impl>::AlphaTC::readLastActivate()
AlphaO3CPU<Impl>::AlphaTC::readLastActivate()
{
return thread->lastActivate;
}
template <class Impl>
Tick
AlphaFullCPU<Impl>::AlphaTC::readLastSuspend()
AlphaO3CPU<Impl>::AlphaTC::readLastSuspend()
{
return thread->lastSuspend;
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::profileClear()
AlphaO3CPU<Impl>::AlphaTC::profileClear()
{}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::profileSample()
AlphaO3CPU<Impl>::AlphaTC::profileSample()
{}
#endif
template <class Impl>
TheISA::MachInst
AlphaFullCPU<Impl>::AlphaTC:: getInst()
AlphaO3CPU<Impl>::AlphaTC:: getInst()
{
return thread->getInst();
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::copyArchRegs(ThreadContext *tc)
AlphaO3CPU<Impl>::AlphaTC::copyArchRegs(ThreadContext *tc)
{
// This function will mess things up unless the ROB is empty and
// there are no instructions in the pipeline.
@@ -421,7 +425,7 @@ AlphaFullCPU<Impl>::AlphaTC::copyArchRegs(ThreadContext *tc)
for (int i = 0; i < AlphaISA::NumIntRegs; ++i) {
renamed_reg = cpu->renameMap[tid].lookup(i);
DPRINTF(FullCPU, "FullCPU: Copying over register %i, had data %lli, "
DPRINTF(O3CPU, "Copying over register %i, had data %lli, "
"now has data %lli.\n",
renamed_reg, cpu->readIntReg(renamed_reg),
tc->readIntReg(i));
@@ -449,19 +453,19 @@ AlphaFullCPU<Impl>::AlphaTC::copyArchRegs(ThreadContext *tc)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::clearArchRegs()
AlphaO3CPU<Impl>::AlphaTC::clearArchRegs()
{}
template <class Impl>
uint64_t
AlphaFullCPU<Impl>::AlphaTC::readIntReg(int reg_idx)
AlphaO3CPU<Impl>::AlphaTC::readIntReg(int reg_idx)
{
return cpu->readArchIntReg(reg_idx, thread->readTid());
}
template <class Impl>
FloatReg
AlphaFullCPU<Impl>::AlphaTC::readFloatReg(int reg_idx, int width)
AlphaO3CPU<Impl>::AlphaTC::readFloatReg(int reg_idx, int width)
{
switch(width) {
case 32:
@@ -476,14 +480,14 @@ AlphaFullCPU<Impl>::AlphaTC::readFloatReg(int reg_idx, int width)
template <class Impl>
FloatReg
AlphaFullCPU<Impl>::AlphaTC::readFloatReg(int reg_idx)
AlphaO3CPU<Impl>::AlphaTC::readFloatReg(int reg_idx)
{
return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
}
template <class Impl>
FloatRegBits
AlphaFullCPU<Impl>::AlphaTC::readFloatRegBits(int reg_idx, int width)
AlphaO3CPU<Impl>::AlphaTC::readFloatRegBits(int reg_idx, int width)
{
DPRINTF(Fault, "Reading floatint register through the TC!\n");
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
@@ -491,14 +495,14 @@ AlphaFullCPU<Impl>::AlphaTC::readFloatRegBits(int reg_idx, int width)
template <class Impl>
FloatRegBits
AlphaFullCPU<Impl>::AlphaTC::readFloatRegBits(int reg_idx)
AlphaO3CPU<Impl>::AlphaTC::readFloatRegBits(int reg_idx)
{
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setIntReg(int reg_idx, uint64_t val)
AlphaO3CPU<Impl>::AlphaTC::setIntReg(int reg_idx, uint64_t val)
{
cpu->setArchIntReg(reg_idx, val, thread->readTid());
@@ -510,7 +514,7 @@ AlphaFullCPU<Impl>::AlphaTC::setIntReg(int reg_idx, uint64_t val)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val, int width)
AlphaO3CPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val, int width)
{
switch(width) {
case 32:
@@ -529,7 +533,7 @@ AlphaFullCPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val, int width)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val)
AlphaO3CPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val)
{
cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
@@ -540,7 +544,7 @@ AlphaFullCPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val,
AlphaO3CPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val,
int width)
{
DPRINTF(Fault, "Setting floatint register through the TC!\n");
@@ -554,7 +558,7 @@ AlphaFullCPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val,
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val)
AlphaO3CPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val)
{
cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
@@ -566,7 +570,7 @@ AlphaFullCPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setPC(uint64_t val)
AlphaO3CPU<Impl>::AlphaTC::setPC(uint64_t val)
{
cpu->setPC(val, thread->readTid());
@@ -578,7 +582,7 @@ AlphaFullCPU<Impl>::AlphaTC::setPC(uint64_t val)
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setNextPC(uint64_t val)
AlphaO3CPU<Impl>::AlphaTC::setNextPC(uint64_t val)
{
cpu->setNextPC(val, thread->readTid());
@@ -590,7 +594,7 @@ AlphaFullCPU<Impl>::AlphaTC::setNextPC(uint64_t val)
template <class Impl>
Fault
AlphaFullCPU<Impl>::AlphaTC::setMiscReg(int misc_reg, const MiscReg &val)
AlphaO3CPU<Impl>::AlphaTC::setMiscReg(int misc_reg, const MiscReg &val)
{
Fault ret_fault = cpu->setMiscReg(misc_reg, val, thread->readTid());
@@ -604,8 +608,8 @@ AlphaFullCPU<Impl>::AlphaTC::setMiscReg(int misc_reg, const MiscReg &val)
template <class Impl>
Fault
AlphaFullCPU<Impl>::AlphaTC::setMiscRegWithEffect(int misc_reg,
const MiscReg &val)
AlphaO3CPU<Impl>::AlphaTC::setMiscRegWithEffect(int misc_reg,
const MiscReg &val)
{
Fault ret_fault = cpu->setMiscRegWithEffect(misc_reg, val,
thread->readTid());
@@ -622,21 +626,21 @@ AlphaFullCPU<Impl>::AlphaTC::setMiscRegWithEffect(int misc_reg,
template <class Impl>
TheISA::IntReg
AlphaFullCPU<Impl>::AlphaTC::getSyscallArg(int i)
AlphaO3CPU<Impl>::AlphaTC::getSyscallArg(int i)
{
return cpu->getSyscallArg(i, thread->readTid());
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setSyscallArg(int i, IntReg val)
AlphaO3CPU<Impl>::AlphaTC::setSyscallArg(int i, IntReg val)
{
cpu->setSyscallArg(i, val, thread->readTid());
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setSyscallReturn(SyscallReturn return_value)
AlphaO3CPU<Impl>::AlphaTC::setSyscallReturn(SyscallReturn return_value)
{
cpu->setSyscallReturn(return_value, thread->readTid());
}
@@ -645,37 +649,37 @@ AlphaFullCPU<Impl>::AlphaTC::setSyscallReturn(SyscallReturn return_value)
template <class Impl>
MiscReg
AlphaFullCPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
AlphaO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
{
return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
MiscReg
AlphaFullCPU<Impl>::readMiscRegWithEffect(int misc_reg, Fault &fault,
unsigned tid)
AlphaO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, Fault &fault,
unsigned tid)
{
return this->regFile.readMiscRegWithEffect(misc_reg, fault, tid);
}
template <class Impl>
Fault
AlphaFullCPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
AlphaO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
{
return this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
Fault
AlphaFullCPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
unsigned tid)
AlphaO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
unsigned tid)
{
return this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
}
template <class Impl>
void
AlphaFullCPU<Impl>::squashFromTC(unsigned tid)
AlphaO3CPU<Impl>::squashFromTC(unsigned tid)
{
this->thread[tid]->inSyscall = true;
this->commit.generateTCEvent(tid);
@@ -685,7 +689,7 @@ AlphaFullCPU<Impl>::squashFromTC(unsigned tid)
template <class Impl>
void
AlphaFullCPU<Impl>::post_interrupt(int int_num, int index)
AlphaO3CPU<Impl>::post_interrupt(int int_num, int index)
{
BaseCPU::post_interrupt(int_num, index);
@@ -697,21 +701,21 @@ AlphaFullCPU<Impl>::post_interrupt(int int_num, int index)
template <class Impl>
int
AlphaFullCPU<Impl>::readIntrFlag()
AlphaO3CPU<Impl>::readIntrFlag()
{
return this->regFile.readIntrFlag();
}
template <class Impl>
void
AlphaFullCPU<Impl>::setIntrFlag(int val)
AlphaO3CPU<Impl>::setIntrFlag(int val)
{
this->regFile.setIntrFlag(val);
}
template <class Impl>
Fault
AlphaFullCPU<Impl>::hwrei(unsigned tid)
AlphaO3CPU<Impl>::hwrei(unsigned tid)
{
// Need to clear the lock flag upon returning from an interrupt.
this->lockFlag = false;
@@ -726,7 +730,7 @@ AlphaFullCPU<Impl>::hwrei(unsigned tid)
template <class Impl>
bool
AlphaFullCPU<Impl>::simPalCheck(int palFunc, unsigned tid)
AlphaO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
{
if (this->thread[tid]->kernelStats)
this->thread[tid]->kernelStats->callpal(palFunc,
@@ -751,7 +755,7 @@ AlphaFullCPU<Impl>::simPalCheck(int palFunc, unsigned tid)
template <class Impl>
void
AlphaFullCPU<Impl>::trap(Fault fault, unsigned tid)
AlphaO3CPU<Impl>::trap(Fault fault, unsigned tid)
{
// Pass the thread's TC into the invoke method.
fault->invoke(this->threadContexts[tid]);
@@ -759,7 +763,7 @@ AlphaFullCPU<Impl>::trap(Fault fault, unsigned tid)
template <class Impl>
void
AlphaFullCPU<Impl>::processInterrupts()
AlphaO3CPU<Impl>::processInterrupts()
{
// Check for interrupts here. For now can copy the code that
// exists within isa_fullsys_traits.hh. Also assume that thread 0
@@ -805,10 +809,12 @@ AlphaFullCPU<Impl>::processInterrupts()
this->setMiscReg(IPR_ISR, summary, 0);
this->setMiscReg(IPR_INTID, ipl, 0);
// Checker needs to know these two registers were updated.
#if USE_CHECKER
if (this->checker) {
this->checker->threadBase()->setMiscReg(IPR_ISR, summary);
this->checker->threadBase()->setMiscReg(IPR_INTID, ipl);
}
#endif
this->trap(Fault(new InterruptFault), 0);
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
this->readMiscReg(IPR_IPLR, 0), ipl, summary);
@@ -821,9 +827,9 @@ AlphaFullCPU<Impl>::processInterrupts()
template <class Impl>
void
AlphaFullCPU<Impl>::syscall(int64_t callnum, int tid)
AlphaO3CPU<Impl>::syscall(int64_t callnum, int tid)
{
DPRINTF(FullCPU, "AlphaFullCPU: [tid:%i] Executing syscall().\n\n", tid);
DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
DPRINTF(Activity,"Activity: syscall() called.\n");
@@ -841,21 +847,21 @@ AlphaFullCPU<Impl>::syscall(int64_t callnum, int tid)
template <class Impl>
TheISA::IntReg
AlphaFullCPU<Impl>::getSyscallArg(int i, int tid)
AlphaO3CPU<Impl>::getSyscallArg(int i, int tid)
{
return this->readArchIntReg(AlphaISA::ArgumentReg0 + i, tid);
}
template <class Impl>
void
AlphaFullCPU<Impl>::setSyscallArg(int i, IntReg val, int tid)
AlphaO3CPU<Impl>::setSyscallArg(int i, IntReg val, int tid)
{
this->setArchIntReg(AlphaISA::ArgumentReg0 + i, val, tid);
}
template <class Impl>
void
AlphaFullCPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
AlphaO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
{
// check for error condition. Alpha syscall convention is to
// indicate success/failure in reg a3 (r19) and put the

View File

@@ -51,7 +51,7 @@ class AlphaDynInst : public BaseDynInst<Impl>
{
public:
/** Typedef for the CPU. */
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
/** Binary machine instruction type. */
typedef TheISA::MachInst MachInst;
@@ -74,7 +74,7 @@ class AlphaDynInst : public BaseDynInst<Impl>
public:
/** BaseDynInst constructor given a binary instruction. */
AlphaDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC, InstSeqNum seq_num,
FullCPU *cpu);
O3CPU *cpu);
/** BaseDynInst constructor given a static inst pointer. */
AlphaDynInst(StaticInstPtr &_staticInst);

View File

@@ -32,7 +32,7 @@
template <class Impl>
AlphaDynInst<Impl>::AlphaDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC,
InstSeqNum seq_num, FullCPU *cpu)
InstSeqNum seq_num, O3CPU *cpu)
: BaseDynInst<Impl>(inst, PC, Pred_PC, seq_num, cpu)
{
initVars();

View File

@@ -41,12 +41,12 @@ template <class Impl>
class AlphaDynInst;
template <class Impl>
class AlphaFullCPU;
class AlphaO3CPU;
/** Implementation specific struct that defines several key types to the
* CPU, the stages within the CPU, the time buffers, and the DynInst.
* The struct defines the ISA, the CPU policy, the specific DynInst, the
* specific FullCPU, and all of the structs from the time buffers to do
* specific O3CPU, and all of the structs from the time buffers to do
* communication.
* This is one of the key things that must be defined for each hardware
* specific CPU implementation.
@@ -67,8 +67,14 @@ struct AlphaSimpleImpl
*/
typedef RefCountingPtr<DynInst> DynInstPtr;
/** The FullCPU type to be used. */
typedef AlphaFullCPU<AlphaSimpleImpl> FullCPU;
/** The O3CPU type to be used. */
typedef AlphaO3CPU<AlphaSimpleImpl> O3CPU;
/** Same typedef, but for CPUType. BaseDynInst may not always use
* an O3 CPU, so it's clearer to call it CPUType instead in that
* case.
*/
typedef O3CPU CPUType;
/** The Params to be passed to each stage. */
typedef AlphaSimpleParams Params;

View File

@@ -42,12 +42,12 @@ class Process;
class System;
/**
* This file defines the parameters that will be used for the AlphaFullCPU.
* This file defines the parameters that will be used for the AlphaO3CPU.
* This must be defined externally so that the Impl can have a params class
* defined that it can pass to all of the individual stages.
*/
class AlphaSimpleParams : public BaseFullCPU::Params
class AlphaSimpleParams : public BaseO3CPU::Params
{
public:

View File

@@ -31,9 +31,9 @@
#include "cpu/o3/bpred_unit_impl.hh"
#include "cpu/o3/alpha_impl.hh"
#include "cpu/o3/alpha_dyn_inst.hh"
#include "cpu/ozone/ozone_impl.hh"
//#include "cpu/ozone/ozone_impl.hh"
//#include "cpu/ozone/simple_impl.hh"
template class BPredUnit<AlphaSimpleImpl>;
template class BPredUnit<OzoneImpl>;
//template class BPredUnit<OzoneImpl>;
//template class BPredUnit<SimpleImpl>;

View File

@@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
* Korey Sewell
*/
#ifndef __CPU_O3_COMMIT_HH__
@@ -67,7 +68,7 @@ class DefaultCommit
{
public:
// Typedefs from the Impl.
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::Params Params;
typedef typename Impl::CPUPol CPUPol;
@@ -145,7 +146,7 @@ class DefaultCommit
void regStats();
/** Sets the CPU pointer. */
void setCPU(FullCPU *cpu_ptr);
void setCPU(O3CPU *cpu_ptr);
/** Sets the list of threads. */
void setThreads(std::vector<Thread *> &threads);
@@ -280,12 +281,20 @@ class DefaultCommit
/** Sets the PC of a specific thread. */
void setPC(uint64_t val, unsigned tid) { PC[tid] = val; }
/** Reads the PC of a specific thread. */
/** Reads the next PC of a specific thread. */
uint64_t readNextPC(unsigned tid) { return nextPC[tid]; }
/** Sets the next PC of a specific thread. */
void setNextPC(uint64_t val, unsigned tid) { nextPC[tid] = val; }
#if THE_ISA != ALPHA_ISA
/** Reads the next NPC of a specific thread. */
uint64_t readNextPC(unsigned tid) { return nextNPC[tid]; }
/** Sets the next NPC of a specific thread. */
void setNextPC(uint64_t val, unsigned tid) { nextNPC[tid] = val; }
#endif
private:
/** Time buffer interface. */
TimeBuffer<TimeStruct> *timeBuffer;
@@ -317,8 +326,8 @@ class DefaultCommit
ROB *rob;
private:
/** Pointer to FullCPU. */
FullCPU *cpu;
/** Pointer to O3CPU. */
O3CPU *cpu;
/** Vector of all of the threads. */
std::vector<Thread *> thread;
@@ -397,6 +406,9 @@ class DefaultCommit
/** The next PC of each thread. */
Addr nextPC[Impl::MaxThreads];
/** The next NPC of each thread. */
Addr nextNPC[Impl::MaxThreads];
/** The sequence number of the youngest valid instruction in the ROB. */
InstSeqNum youngestSeqNum[Impl::MaxThreads];

View File

@@ -28,6 +28,9 @@
* Authors: Kevin Lim
*/
#include "config/full_system.hh"
#include "config/use_checker.hh"
#include <algorithm>
#include <string>
@@ -219,14 +222,14 @@ DefaultCommit<Impl>::regStats()
template <class Impl>
void
DefaultCommit<Impl>::setCPU(FullCPU *cpu_ptr)
DefaultCommit<Impl>::setCPU(O3CPU *cpu_ptr)
{
DPRINTF(Commit, "Commit: Setting CPU pointer.\n");
cpu = cpu_ptr;
// Commit must broadcast the number of free entries it has at the start of
// the simulation, so it starts as active.
cpu->activateStage(FullCPU::CommitIdx);
cpu->activateStage(O3CPU::CommitIdx);
trapLatency = cpu->cycles(trapLatency);
fetchTrapLatency = cpu->cycles(fetchTrapLatency);
@@ -395,10 +398,10 @@ DefaultCommit<Impl>::updateStatus()
if (_nextStatus == Inactive && _status == Active) {
DPRINTF(Activity, "Deactivating stage.\n");
cpu->deactivateStage(FullCPU::CommitIdx);
cpu->deactivateStage(O3CPU::CommitIdx);
} else if (_nextStatus == Active && _status == Inactive) {
DPRINTF(Activity, "Activating stage.\n");
cpu->activateStage(FullCPU::CommitIdx);
cpu->activateStage(O3CPU::CommitIdx);
}
_status = _nextStatus;
@@ -907,7 +910,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
// and committed this instruction.
thread[tid]->funcExeInst--;
head_inst->reachedCommit = true;
head_inst->setAtCommit();
if (head_inst->isNonSpeculative() ||
head_inst->isStoreConditional() ||
@@ -972,11 +975,13 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
head_inst->setCompleted();
}
#if USE_CHECKER
// Use checker prior to updating anything due to traps or PC
// based events.
if (cpu->checker) {
cpu->checker->tick(head_inst);
cpu->checker->verify(head_inst);
}
#endif
// Check if the instruction caused a fault. If so, trap.
Fault inst_fault = head_inst->getFault();
@@ -992,9 +997,11 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
return false;
}
#if USE_CHECKER
if (cpu->checker && head_inst->isStore()) {
cpu->checker->tick(head_inst);
cpu->checker->verify(head_inst);
}
#endif
assert(!thread[tid]->inSyscall);

View File

@@ -26,9 +26,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
* Korey Sewell
*/
#include "config/full_system.hh"
#include "config/use_checker.hh"
#if FULL_SYSTEM
#include "sim/system.hh"
@@ -50,13 +52,13 @@
using namespace std;
using namespace TheISA;
BaseFullCPU::BaseFullCPU(Params *params)
BaseO3CPU::BaseO3CPU(Params *params)
: BaseCPU(params), cpu_id(0)
{
}
void
BaseFullCPU::regStats()
BaseO3CPU::regStats()
{
BaseCPU::regStats();
}
@@ -83,7 +85,7 @@ FullO3CPU<Impl>::TickEvent::description()
template <class Impl>
FullO3CPU<Impl>::FullO3CPU(Params *params)
: BaseFullCPU(params),
: BaseO3CPU(params),
tickEvent(this),
removeInstsThisCycle(false),
fetch(params),
@@ -131,6 +133,9 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
{
_status = Idle;
checker = NULL;
#if USE_CHECKER
if (params->checker) {
BaseCPU *temp_checker = params->checker;
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
@@ -138,9 +143,8 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
#if FULL_SYSTEM
checker->setSystem(params->system);
#endif
} else {
checker = NULL;
}
#endif
#if !FULL_SYSTEM
thread.resize(number_of_threads);
@@ -261,9 +265,9 @@ template <class Impl>
void
FullO3CPU<Impl>::fullCPURegStats()
{
BaseFullCPU::regStats();
BaseO3CPU::regStats();
// Register any of the FullCPU's stats here.
// Register any of the O3CPU's stats here.
timesIdled
.name(name() + ".timesIdled")
.desc("Number of times that the entire CPU went into an idle state and"
@@ -319,7 +323,7 @@ template <class Impl>
void
FullO3CPU<Impl>::tick()
{
DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n");
DPRINTF(O3CPU, "\n\nFullO3CPU: Ticking main, FullO3CPU.\n");
++numCycles;
@@ -418,7 +422,7 @@ template <class Impl>
void
FullO3CPU<Impl>::insertThread(unsigned tid)
{
DPRINTF(FullCPU,"[tid:%i] Initializing thread data");
DPRINTF(O3CPU,"[tid:%i] Initializing thread data");
// Will change now that the PC and thread state is internal to the CPU
// and not in the ThreadContext.
#if 0
@@ -465,7 +469,7 @@ template <class Impl>
void
FullO3CPU<Impl>::removeThread(unsigned tid)
{
DPRINTF(FullCPU,"[tid:%i] Removing thread data");
DPRINTF(O3CPU,"[tid:%i] Removing thread data");
#if 0
//Unbind Int Regs from Rename Map
for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
@@ -511,37 +515,37 @@ template <class Impl>
void
FullO3CPU<Impl>::activateWhenReady(int tid)
{
DPRINTF(FullCPU,"[tid:%i]: Checking if resources are available for incoming"
DPRINTF(O3CPU,"[tid:%i]: Checking if resources are available for incoming"
"(e.g. PhysRegs/ROB/IQ/LSQ) \n",
tid);
bool ready = true;
if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) {
DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
"Phys. Int. Regs.\n",
tid);
ready = false;
} else if (freeList.numFreeFloatRegs() >= TheISA::NumFloatRegs) {
DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
"Phys. Float. Regs.\n",
tid);
ready = false;
} else if (commit.rob->numFreeEntries() >=
commit.rob->entryAmount(activeThreads.size() + 1)) {
DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
"ROB entries.\n",
tid);
ready = false;
} else if (iew.instQueue.numFreeEntries() >=
iew.instQueue.entryAmount(activeThreads.size() + 1)) {
DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
"IQ entries.\n",
tid);
ready = false;
} else if (iew.ldstQueue.numFreeEntries() >=
iew.ldstQueue.entryAmount(activeThreads.size() + 1)) {
DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough "
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
"LSQ entries.\n",
tid);
ready = false;
@@ -575,7 +579,7 @@ FullO3CPU<Impl>::activateContext(int tid, int delay)
if (isActive == activeThreads.end()) {
//May Need to Re-code this if the delay variable is the
//delay needed for thread to activate
DPRINTF(FullCPU, "Adding Thread %i to active threads list\n",
DPRINTF(O3CPU, "Adding Thread %i to active threads list\n",
tid);
activeThreads.push_back(tid);
@@ -597,7 +601,7 @@ template <class Impl>
void
FullO3CPU<Impl>::suspendContext(int tid)
{
DPRINTF(FullCPU,"[tid: %i]: Suspended ...\n", tid);
DPRINTF(O3CPU,"[tid: %i]: Suspended ...\n", tid);
unscheduleTickEvent();
_status = Idle;
/*
@@ -606,7 +610,7 @@ FullO3CPU<Impl>::suspendContext(int tid)
activeThreads.begin(), activeThreads.end(), tid);
if (isActive != activeThreads.end()) {
DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n",
DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
tid);
activeThreads.erase(isActive);
}
@@ -617,14 +621,14 @@ template <class Impl>
void
FullO3CPU<Impl>::deallocateContext(int tid)
{
DPRINTF(FullCPU,"[tid:%i]: Deallocating ...", tid);
DPRINTF(O3CPU,"[tid:%i]: Deallocating ...", tid);
/*
//Remove From Active List, if Active
list<unsigned>::iterator isActive = find(
activeThreads.begin(), activeThreads.end(), tid);
if (isActive != activeThreads.end()) {
DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n",
DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
tid);
activeThreads.erase(isActive);
@@ -637,14 +641,14 @@ template <class Impl>
void
FullO3CPU<Impl>::haltContext(int tid)
{
DPRINTF(FullCPU,"[tid:%i]: Halted ...", tid);
DPRINTF(O3CPU,"[tid:%i]: Halted ...", tid);
/*
//Remove From Active List, if Active
list<unsigned>::iterator isActive = find(
activeThreads.begin(), activeThreads.end(), tid);
if (isActive != activeThreads.end()) {
DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n",
DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
tid);
activeThreads.erase(isActive);
@@ -730,7 +734,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
if (isActive == activeThreads.end()) {
//May Need to Re-code this if the delay variable is the delay
//needed for thread to activate
DPRINTF(FullCPU, "Adding Thread %i to active threads list\n",
DPRINTF(O3CPU, "Adding Thread %i to active threads list\n",
tid);
activeThreads.push_back(tid);
@@ -922,6 +926,22 @@ FullO3CPU<Impl>::setNextPC(uint64_t val,unsigned tid)
commit.setNextPC(val, tid);
}
#if THE_ISA != ALPHA_ISA
template <class Impl>
uint64_t
FullO3CPU<Impl>::readNextNPC(unsigned tid)
{
return commit.readNextNPC(tid);
}
template <class Impl>
void
FullO3CPU<Impl>::setNextNNPC(uint64_t val,unsigned tid)
{
commit.setNextNPC(val, tid);
}
#endif
template <class Impl>
typename FullO3CPU<Impl>::ListIt
FullO3CPU<Impl>::addInst(DynInstPtr &inst)
@@ -958,7 +978,7 @@ template <class Impl>
void
FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst)
{
DPRINTF(FullCPU, "FullCPU: Removing committed instruction [tid:%i] PC %#x "
DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %#x "
"[sn:%lli]\n",
inst->threadNumber, inst->readPC(), inst->seqNum);
@@ -972,7 +992,7 @@ template <class Impl>
void
FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid)
{
DPRINTF(FullCPU, "FullCPU: Thread %i: Deleting instructions from instruction"
DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
" list.\n", tid);
ListIt end_it;
@@ -982,12 +1002,12 @@ FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid)
if (instList.empty()) {
return;
} else if (rob.isEmpty(/*tid*/)) {
DPRINTF(FullCPU, "FullCPU: ROB is empty, squashing all insts.\n");
DPRINTF(O3CPU, "ROB is empty, squashing all insts.\n");
end_it = instList.begin();
rob_empty = true;
} else {
end_it = (rob.readTailInst(tid))->getInstListIt();
DPRINTF(FullCPU, "FullCPU: ROB is not empty, squashing insts not in ROB.\n");
DPRINTF(O3CPU, "ROB is not empty, squashing insts not in ROB.\n");
}
removeInstsThisCycle = true;
@@ -1026,7 +1046,7 @@ FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num,
inst_iter--;
DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
DPRINTF(O3CPU, "Deleting instructions from instruction "
"list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
tid, seq_num, (*inst_iter)->seqNum);
@@ -1048,7 +1068,7 @@ inline void
FullO3CPU<Impl>::squashInstIt(const ListIt &instIt, const unsigned &tid)
{
if ((*instIt)->threadNumber == tid) {
DPRINTF(FullCPU, "FullCPU: Squashing instruction, "
DPRINTF(O3CPU, "Squashing instruction, "
"[tid:%i] [sn:%lli] PC %#x\n",
(*instIt)->threadNumber,
(*instIt)->seqNum,
@@ -1069,7 +1089,7 @@ void
FullO3CPU<Impl>::cleanUpRemovedInsts()
{
while (!removeList.empty()) {
DPRINTF(FullCPU, "FullCPU: Removing instruction, "
DPRINTF(O3CPU, "Removing instruction, "
"[tid:%i] [sn:%lli] PC %#x\n",
(*removeList.front())->threadNumber,
(*removeList.front())->seqNum,

View File

@@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
* Korey Sewell
*/
#ifndef __CPU_O3_CPU_HH__
@@ -56,13 +57,13 @@ class ThreadContext;
class MemObject;
class Process;
class BaseFullCPU : public BaseCPU
class BaseO3CPU : public BaseCPU
{
//Stuff that's pretty ISA independent will go here.
public:
typedef BaseCPU::Params Params;
BaseFullCPU(Params *params);
BaseO3CPU(Params *params);
void regStats();
@@ -78,7 +79,7 @@ class BaseFullCPU : public BaseCPU
* tick() function for the CPU is defined here.
*/
template <class Impl>
class FullO3CPU : public BaseFullCPU
class FullO3CPU : public BaseO3CPU
{
public:
typedef TheISA::FloatReg FloatReg;
@@ -299,6 +300,12 @@ class FullO3CPU : public BaseFullCPU
/** Sets the next PC of a specific thread. */
void setNextPC(uint64_t val, unsigned tid);
/** Reads the next NPC of a specific thread. */
uint64_t readNextNPC(unsigned tid);
/** Sets the next NPC of a specific thread. */
void setNextNPC(uint64_t val, unsigned tid);
/** Function to add instruction onto the head of the list of the
* instructions. Used when new instructions are fetched.
*/

View File

@@ -48,7 +48,7 @@ class DefaultDecode
{
private:
// Typedefs from the Impl.
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::Params Params;
typedef typename Impl::CPUPol CPUPol;
@@ -95,7 +95,7 @@ class DefaultDecode
void regStats();
/** Sets CPU pointer. */
void setCPU(FullCPU *cpu_ptr);
void setCPU(O3CPU *cpu_ptr);
/** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
@@ -189,7 +189,7 @@ class DefaultDecode
private:
// Interfaces to objects outside of decode.
/** CPU interface. */
FullCPU *cpu;
O3CPU *cpu;
/** Time buffer interface. */
TimeBuffer<TimeStruct> *timeBuffer;

View File

@@ -112,7 +112,7 @@ DefaultDecode<Impl>::regStats()
template<class Impl>
void
DefaultDecode<Impl>::setCPU(FullCPU *cpu_ptr)
DefaultDecode<Impl>::setCPU(O3CPU *cpu_ptr)
{
DPRINTF(Decode, "Setting CPU pointer.\n");
cpu = cpu_ptr;
@@ -296,7 +296,7 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
for (int i=0; i<fromFetch->size; i++) {
if (fromFetch->insts[i]->threadNumber == tid &&
fromFetch->insts[i]->seqNum > inst->seqNum) {
fromFetch->insts[i]->squashed = true;
fromFetch->insts[i]->setSquashed();
}
}
@@ -345,7 +345,7 @@ DefaultDecode<Impl>::squash(unsigned tid)
for (int i=0; i<fromFetch->size; i++) {
if (fromFetch->insts[i]->threadNumber == tid) {
fromFetch->insts[i]->squashed = true;
fromFetch->insts[i]->setSquashed();
squash_count++;
}
}
@@ -427,7 +427,7 @@ DefaultDecode<Impl>::updateStatus()
DPRINTF(Activity, "Activating stage.\n");
cpu->activateStage(FullCPU::DecodeIdx);
cpu->activateStage(O3CPU::DecodeIdx);
}
} else {
// If it's not unblocking, then decode will not have any internal
@@ -436,7 +436,7 @@ DefaultDecode<Impl>::updateStatus()
_status = Inactive;
DPRINTF(Activity, "Deactivating stage.\n");
cpu->deactivateStage(FullCPU::DecodeIdx);
cpu->deactivateStage(O3CPU::DecodeIdx);
}
}
}

View File

@@ -68,6 +68,8 @@ class DependencyGraph
: numEntries(0), memAllocCounter(0), nodesTraversed(0), nodesRemoved(0)
{ }
~DependencyGraph();
/** Resize the dependency graph to have num_entries registers. */
void resize(int num_entries);
@@ -120,6 +122,12 @@ class DependencyGraph
uint64_t nodesRemoved;
};
template <class DynInstPtr>
DependencyGraph<DynInstPtr>::~DependencyGraph()
{
delete [] dependGraph;
}
template <class DynInstPtr>
void
DependencyGraph<DynInstPtr>::resize(int num_entries)

View File

@@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
* Korey Sewell
*/
#ifndef __CPU_O3_FETCH_HH__
@@ -57,7 +58,7 @@ class DefaultFetch
typedef typename Impl::CPUPol CPUPol;
typedef typename Impl::DynInst DynInst;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::Params Params;
/** Typedefs from the CPU policy. */
@@ -164,7 +165,7 @@ class DefaultFetch
void regStats();
/** Sets CPU pointer. */
void setCPU(FullCPU *cpu_ptr);
void setCPU(O3CPU *cpu_ptr);
/** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
@@ -296,8 +297,8 @@ class DefaultFetch
int branchCount();
private:
/** Pointer to the FullCPU. */
FullCPU *cpu;
/** Pointer to the O3CPU. */
O3CPU *cpu;
/** Time buffer interface. */
TimeBuffer<TimeStruct> *timeBuffer;
@@ -335,6 +336,15 @@ class DefaultFetch
/** Per-thread next PC. */
Addr nextPC[Impl::MaxThreads];
#if THE_ISA != ALPHA_ISA
/** Per-thread next Next PC.
* This is not a real register but is used for
* architectures that use a branch-delay slot.
* (such as MIPS or Sparc)
*/
Addr nextNPC[Impl::MaxThreads];
#endif
/** Memory request used to access cache. */
RequestPtr memReq[Impl::MaxThreads];

View File

@@ -26,8 +26,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
* Korey Sewell
*/
#include "config/use_checker.hh"
#include "arch/isa_traits.hh"
#include "arch/utility.hh"
#include "cpu/checker/cpu.hh"
@@ -268,7 +271,7 @@ DefaultFetch<Impl>::regStats()
template<class Impl>
void
DefaultFetch<Impl>::setCPU(FullCPU *cpu_ptr)
DefaultFetch<Impl>::setCPU(O3CPU *cpu_ptr)
{
DPRINTF(Fetch, "Setting the CPU pointer.\n");
cpu = cpu_ptr;
@@ -280,9 +283,11 @@ DefaultFetch<Impl>::setCPU(FullCPU *cpu_ptr)
icachePort->setPeer(mem_dport);
mem_dport->setPeer(icachePort);
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->setIcachePort(icachePort);
}
#endif
// Fetch needs to start fetching instructions at the very beginning,
// so it must start up in active state.
@@ -330,6 +335,9 @@ DefaultFetch<Impl>::initStage()
for (int tid = 0; tid < numThreads; tid++) {
PC[tid] = cpu->readPC(tid);
nextPC[tid] = cpu->readNextPC(tid);
#if THE_ISA != ALPHA_ISA
nextNPC[tid] = cpu->readNextNPC(tid);
#endif
}
}
@@ -404,6 +412,9 @@ DefaultFetch<Impl>::takeOverFrom()
stalls[i].commit = 0;
PC[i] = cpu->readPC(i);
nextPC[i] = cpu->readNextPC(i);
#if THE_ISA != ALPHA_ISA
nextNPC[i] = cpu->readNextNPC(i);
#endif
fetchStatus[i] = Running;
}
numInst = 0;
@@ -430,7 +441,7 @@ DefaultFetch<Impl>::switchToActive()
if (_status == Inactive) {
DPRINTF(Activity, "Activating stage.\n");
cpu->activateStage(FullCPU::FetchIdx);
cpu->activateStage(O3CPU::FetchIdx);
_status = Active;
}
@@ -443,7 +454,7 @@ DefaultFetch<Impl>::switchToInactive()
if (_status == Active) {
DPRINTF(Activity, "Deactivating stage.\n");
cpu->deactivateStage(FullCPU::FetchIdx);
cpu->deactivateStage(O3CPU::FetchIdx);
_status = Inactive;
}
@@ -662,7 +673,7 @@ DefaultFetch<Impl>::updateFetchStatus()
"completion\n",tid);
}
cpu->activateStage(FullCPU::FetchIdx);
cpu->activateStage(O3CPU::FetchIdx);
}
return Active;
@@ -673,7 +684,7 @@ DefaultFetch<Impl>::updateFetchStatus()
if (_status == Active) {
DPRINTF(Activity, "Deactivating stage.\n");
cpu->deactivateStage(FullCPU::FetchIdx);
cpu->deactivateStage(O3CPU::FetchIdx);
}
return Inactive;
@@ -1024,7 +1035,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
fetch_PC = next_PC;
if (instruction->isQuiesce()) {
warn("%lli: Quiesce instruction encountered, halting fetch!",
warn("cycle %lli: Quiesce instruction encountered, halting fetch!",
curTick);
fetchStatus[tid] = QuiescePending;
++numInst;
@@ -1045,8 +1056,17 @@ DefaultFetch<Impl>::fetch(bool &status_change)
if (fault == NoFault) {
DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n",tid, next_PC);
#if THE_ISA == ALPHA_ISA
PC[tid] = next_PC;
nextPC[tid] = next_PC + instSize;
#else
PC[tid] = next_PC;
nextPC[tid] = next_PC + instSize;
nextPC[tid] = next_PC + instSize;
thread->setNextPC(thread->readNextNPC());
thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
#endif
} else {
// We shouldn't be in an icache miss and also have a fault (an ITB
// miss)
@@ -1089,9 +1109,9 @@ DefaultFetch<Impl>::fetch(bool &status_change)
fetchStatus[tid] = TrapPending;
status_change = true;
warn("%lli fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
warn("cycle %lli: fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
#else // !FULL_SYSTEM
warn("%lli fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
warn("cycle %lli: fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
#endif // FULL_SYSTEM
}
}
@@ -1260,6 +1280,6 @@ int
DefaultFetch<Impl>::branchCount()
{
list<unsigned>::iterator threads = (*activeThreads).begin();
warn("Branch Count Fetch policy unimplemented\n");
return *threads;
}

View File

@@ -31,7 +31,7 @@
#include <sstream>
#include "cpu/o3/fu_pool.hh"
#include "encumbered/cpu/full/fu_pool.hh"
#include "cpu/func_unit.hh"
#include "sim/builder.hh"
using namespace std;

View File

@@ -68,7 +68,7 @@ class DefaultIEW
//Typedefs from Impl
typedef typename Impl::CPUPol CPUPol;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::Params Params;
typedef typename CPUPol::IQ IQ;
@@ -80,7 +80,7 @@ class DefaultIEW
typedef typename CPUPol::RenameStruct RenameStruct;
typedef typename CPUPol::IssueStruct IssueStruct;
friend class Impl::FullCPU;
friend class Impl::O3CPU;
friend class CPUPol::IQ;
public:
@@ -126,7 +126,7 @@ class DefaultIEW
void initStage();
/** Sets CPU pointer for IEW, IQ, and LSQ. */
void setCPU(FullCPU *cpu_ptr);
void setCPU(O3CPU *cpu_ptr);
/** Sets main time buffer used for backwards communication. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
@@ -331,7 +331,7 @@ class DefaultIEW
private:
/** CPU pointer. */
FullCPU *cpu;
O3CPU *cpu;
/** Records if IEW has written to the time buffer this cycle, so that the
* CPU can deschedule itself if there is no activity.

View File

@@ -276,7 +276,7 @@ DefaultIEW<Impl>::initStage()
template<class Impl>
void
DefaultIEW<Impl>::setCPU(FullCPU *cpu_ptr)
DefaultIEW<Impl>::setCPU(O3CPU *cpu_ptr)
{
DPRINTF(IEW, "Setting CPU pointer.\n");
cpu = cpu_ptr;
@@ -284,7 +284,7 @@ DefaultIEW<Impl>::setCPU(FullCPU *cpu_ptr)
instQueue.setCPU(cpu_ptr);
ldstQueue.setCPU(cpu_ptr);
cpu->activateStage(FullCPU::IEWIdx);
cpu->activateStage(O3CPU::IEWIdx);
}
template<class Impl>
@@ -579,7 +579,7 @@ DefaultIEW<Impl>::validInstsFromRename()
unsigned inst_count = 0;
for (int i=0; i<fromRename->size; i++) {
if (!fromRename->insts[i]->squashed)
if (!fromRename->insts[i]->isSquashed())
inst_count++;
}
@@ -857,7 +857,7 @@ inline void
DefaultIEW<Impl>::activateStage()
{
DPRINTF(Activity, "Activating stage.\n");
cpu->activateStage(FullCPU::IEWIdx);
cpu->activateStage(O3CPU::IEWIdx);
}
template <class Impl>
@@ -865,7 +865,7 @@ inline void
DefaultIEW<Impl>::deactivateStage()
{
DPRINTF(Activity, "Deactivating stage.\n");
cpu->deactivateStage(FullCPU::IEWIdx);
cpu->deactivateStage(O3CPU::IEWIdx);
}
template<class Impl>

View File

@@ -68,7 +68,7 @@ class InstructionQueue
{
public:
//Typedefs from the Impl.
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::Params Params;
@@ -80,7 +80,7 @@ class InstructionQueue
// Typedef of iterator through the list of instructions.
typedef typename std::list<DynInstPtr>::iterator ListIt;
friend class Impl::FullCPU;
friend class Impl::O3CPU;
/** FU completion event class. */
class FUCompletion : public Event {
@@ -125,7 +125,7 @@ class InstructionQueue
void resetState();
/** Sets CPU pointer. */
void setCPU(FullCPU *_cpu) { cpu = _cpu; }
void setCPU(O3CPU *_cpu) { cpu = _cpu; }
/** Sets active threads list. */
void setActiveThreads(std::list<unsigned> *at_ptr);
@@ -252,7 +252,7 @@ class InstructionQueue
/////////////////////////
/** Pointer to the CPU. */
FullCPU *cpu;
O3CPU *cpu;
/** Cache interface. */
MemInterface *dcacheInterface;

View File

@@ -776,7 +776,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
// complete.
++freeEntries;
count[tid]--;
issuing_inst->removeInIQ();
issuing_inst->clearInIQ();
} else {
memDepUnit[tid].issue(issuing_inst);
}
@@ -1082,7 +1082,7 @@ InstructionQueue<Impl>::doSquash(unsigned tid)
// inst will flow through the rest of the pipeline.
squashed_inst->setIssued();
squashed_inst->setCanCommit();
squashed_inst->removeInIQ();
squashed_inst->clearInIQ();
//Update Thread IQ Count
count[squashed_inst->threadNumber]--;

View File

@@ -44,7 +44,7 @@ template <class Impl>
class LSQ {
public:
typedef typename Impl::Params Params;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::CPUPol::IEW IEW;
typedef typename Impl::CPUPol::LSQUnit LSQUnit;
@@ -68,7 +68,7 @@ class LSQ {
/** Sets the pointer to the list of active threads. */
void setActiveThreads(std::list<unsigned> *at_ptr);
/** Sets the CPU pointer. */
void setCPU(FullCPU *cpu_ptr);
void setCPU(O3CPU *cpu_ptr);
/** Sets the IEW stage pointer. */
void setIEW(IEW *iew_ptr);
/** Switches out the LSQ. */
@@ -275,7 +275,7 @@ class LSQ {
LSQUnit thread[Impl::MaxThreads];
/** The CPU pointer. */
FullCPU *cpu;
O3CPU *cpu;
/** The IEW stage pointer. */
IEW *iewStage;

View File

@@ -126,7 +126,7 @@ LSQ<Impl>::setActiveThreads(list<unsigned> *at_ptr)
template<class Impl>
void
LSQ<Impl>::setCPU(FullCPU *cpu_ptr)
LSQ<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;

View File

@@ -61,7 +61,7 @@ class LSQUnit {
typedef TheISA::IntReg IntReg;
public:
typedef typename Impl::Params Params;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::CPUPol::IEW IEW;
typedef typename Impl::CPUPol::IssueStruct IssueStruct;
@@ -81,7 +81,7 @@ class LSQUnit {
void regStats();
/** Sets the CPU pointer. */
void setCPU(FullCPU *cpu_ptr);
void setCPU(O3CPU *cpu_ptr);
/** Sets the IEW stage pointer. */
void setIEW(IEW *iew_ptr)
@@ -232,7 +232,7 @@ class LSQUnit {
private:
/** Pointer to the CPU. */
FullCPU *cpu;
O3CPU *cpu;
/** Pointer to the IEW stage. */
IEW *iewStage;
@@ -249,13 +249,13 @@ class LSQUnit {
{
protected:
/** Pointer to CPU. */
FullCPU *cpu;
O3CPU *cpu;
/** Pointer to LSQ. */
LSQUnit *lsq;
public:
/** Default constructor. */
DcachePort(FullCPU *_cpu, LSQUnit *_lsq)
DcachePort(O3CPU *_cpu, LSQUnit *_lsq)
: Port(_lsq->name() + "-dport"), cpu(_cpu), lsq(_lsq)
{ }
@@ -527,7 +527,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
// at the head of the LSQ and are ready to commit (at the head of the ROB
// too).
if (req->getFlags() & UNCACHEABLE &&
(load_idx != loadHead || !load_inst->reachedCommit)) {
(load_idx != loadHead || !load_inst->isAtCommit())) {
iewStage->rescheduleMemInst(load_inst);
++lsqRescheduledLoads;
return TheISA::genMachineCheckFault();

View File

@@ -29,6 +29,8 @@
* Korey Sewell
*/
#include "config/use_checker.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/o3/lsq_unit.hh"
#include "base/str.hh"
@@ -171,7 +173,7 @@ LSQUnit<Impl>::init(Params *params, unsigned maxLQEntries,
template<class Impl>
void
LSQUnit<Impl>::setCPU(FullCPU *cpu_ptr)
LSQUnit<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
dcachePort = new DcachePort(cpu, this);
@@ -180,9 +182,11 @@ LSQUnit<Impl>::setCPU(FullCPU *cpu_ptr)
dcachePort->setPeer(mem_dport);
mem_dport->setPeer(dcachePort);
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->setDcachePort(dcachePort);
}
#endif
}
template<class Impl>
@@ -710,7 +714,7 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
}
// Clear the smart pointer to make sure it is decremented.
loadQueue[load_idx]->squashed = true;
loadQueue[load_idx]->setSquashed();
loadQueue[load_idx] = NULL;
--loads;
@@ -754,7 +758,7 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
}
// Clear the smart pointer to make sure it is decremented.
storeQueue[store_idx].inst->squashed = true;
storeQueue[store_idx].inst->setSquashed();
storeQueue[store_idx].inst = NULL;
storeQueue[store_idx].canWB = 0;
@@ -788,9 +792,11 @@ LSQUnit<Impl>::storePostSend(Packet *pkt)
// only works so long as the checker doesn't try to
// verify the value in memory for stores.
storeQueue[storeWBIdx].inst->setCompleted();
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->tick(storeQueue[storeWBIdx].inst);
cpu->checker->verify(storeQueue[storeWBIdx].inst);
}
#endif
}
if (pkt->result != Packet::Success) {
@@ -884,9 +890,11 @@ LSQUnit<Impl>::completeStore(int store_idx)
// Tell the checker we've completed this instruction. Some stores
// may get reported twice to the checker, but the checker can
// handle that case.
#if USE_CHECKER
if (cpu->checker) {
cpu->checker->tick(storeQueue[store_idx].inst);
cpu->checker->verify(storeQueue[store_idx].inst);
}
#endif
}
template <class Impl>

View File

@@ -72,7 +72,7 @@ class PhysRegFile
// Will make these registers public for now, but they probably should
// be private eventually with some accessor functions.
public:
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
/**
* Constructs a physical register file with the specified amount of
@@ -278,11 +278,11 @@ class PhysRegFile
private:
/** CPU pointer. */
FullCPU *cpu;
O3CPU *cpu;
public:
/** Sets the CPU pointer. */
void setCPU(FullCPU *cpu_ptr) { cpu = cpu_ptr; }
void setCPU(O3CPU *cpu_ptr) { cpu = cpu_ptr; }
/** Number of physical integer registers. */
unsigned numPhysicalIntRegs;

View File

@@ -55,7 +55,7 @@ class DefaultRename
// Typedefs from the Impl.
typedef typename Impl::CPUPol CPUPol;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::Params Params;
// Typedefs from the CPUPol
@@ -115,7 +115,7 @@ class DefaultRename
void regStats();
/** Sets CPU pointer. */
void setCPU(FullCPU *cpu_ptr);
void setCPU(O3CPU *cpu_ptr);
/** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
@@ -291,7 +291,7 @@ class DefaultRename
std::list<RenameHistory> historyBuffer[Impl::MaxThreads];
/** Pointer to CPU. */
FullCPU *cpu;
O3CPU *cpu;
/** Pointer to main time buffer used for backwards communication. */
TimeBuffer<TimeStruct> *timeBuffer;

View File

@@ -162,7 +162,7 @@ DefaultRename<Impl>::regStats()
template <class Impl>
void
DefaultRename<Impl>::setCPU(FullCPU *cpu_ptr)
DefaultRename<Impl>::setCPU(O3CPU *cpu_ptr)
{
DPRINTF(Rename, "Setting CPU pointer.\n");
cpu = cpu_ptr;
@@ -341,7 +341,7 @@ DefaultRename<Impl>::squash(unsigned tid)
for (int i=0; i<fromDecode->size; i++) {
if (fromDecode->insts[i]->threadNumber == tid) {
fromDecode->insts[i]->squashed = true;
fromDecode->insts[i]->setSquashed();
wroteToTimeBuffer = true;
squashCount++;
}
@@ -755,7 +755,7 @@ DefaultRename<Impl>::updateStatus()
DPRINTF(Activity, "Activating stage.\n");
cpu->activateStage(FullCPU::RenameIdx);
cpu->activateStage(O3CPU::RenameIdx);
}
} else {
// If it's not unblocking, then rename will not have any internal
@@ -764,7 +764,7 @@ DefaultRename<Impl>::updateStatus()
_status = Inactive;
DPRINTF(Activity, "Deactivating stage.\n");
cpu->deactivateStage(FullCPU::RenameIdx);
cpu->deactivateStage(O3CPU::RenameIdx);
}
}
}
@@ -1022,7 +1022,7 @@ DefaultRename<Impl>::validInsts()
unsigned inst_count = 0;
for (int i=0; i<fromDecode->size; i++) {
if (!fromDecode->insts[i]->squashed)
if (!fromDecode->insts[i]->isSquashed())
inst_count++;
}

View File

@@ -45,7 +45,7 @@ class ROB
typedef TheISA::RegIndex RegIndex;
public:
//Typedefs from the Impl.
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef std::pair<RegIndex, PhysRegIndex> UnmapInfo;
@@ -90,7 +90,7 @@ class ROB
* is created within.
* @param cpu_ptr Pointer to the implementation specific full CPU object.
*/
void setCPU(FullCPU *cpu_ptr);
void setCPU(O3CPU *cpu_ptr);
/** Sets pointer to the list of active threads.
* @param at_ptr Pointer to the list of active threads.
@@ -257,7 +257,7 @@ class ROB
private:
/** Pointer to the CPU. */
FullCPU *cpu;
O3CPU *cpu;
/** Active Threads in CPU */
std::list<unsigned>* activeThreads;

View File

@@ -100,7 +100,7 @@ ROB<Impl>::name() const
template <class Impl>
void
ROB<Impl>::setCPU(FullCPU *cpu_ptr)
ROB<Impl>::setCPU(O3CPU *cpu_ptr)
{
cpu = cpu_ptr;
@@ -276,7 +276,7 @@ ROB<Impl>::retireHead(unsigned tid)
--numInstsInROB;
--threadEntries[tid];
head_inst->removeInROB();
head_inst->clearInROB();
head_inst->setCommitted();
instList[tid].erase(head_it);

View File

@@ -58,11 +58,11 @@ class Process;
template <class Impl>
struct O3ThreadState : public ThreadState {
typedef ThreadContext::Status Status;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::O3CPU O3CPU;
private:
/** Pointer to the CPU. */
FullCPU *cpu;
O3CPU *cpu;
public:
/** Whether or not the thread is currently in syscall mode, and
* thus able to be externally updated without squashing.
@@ -75,12 +75,12 @@ struct O3ThreadState : public ThreadState {
bool trapPending;
#if FULL_SYSTEM
O3ThreadState(FullCPU *_cpu, int _thread_num)
O3ThreadState(O3CPU *_cpu, int _thread_num)
: ThreadState(-1, _thread_num),
inSyscall(0), trapPending(0)
{ }
#else
O3ThreadState(FullCPU *_cpu, int _thread_num, Process *_process, int _asid,
O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid,
MemObject *mem)
: ThreadState(-1, _thread_num, mem, _process, _asid),
cpu(_cpu), inSyscall(0), trapPending(0)

View File

@@ -87,12 +87,12 @@ addPkg('m5')
pyzip_files.append('m5/defines.py')
pyzip_files.append(join(env['ROOT'], 'util/pbs/jobfile.py'))
env.Command(['swig/main_wrap.cc', 'm5/main.py'],
'swig/main.i',
env.Command(['swig/cc_main_wrap.cc', 'm5/cc_main.py'],
'swig/cc_main.i',
'$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
'-o ${TARGETS[0]} $SOURCES')
pyzip_dep_files.append('m5/main.py')
pyzip_dep_files.append('m5/cc_main.py')
# Action function to build the zip archive. Uses the PyZipFile module
# included in the standard Python library.

View File

@@ -30,11 +30,11 @@
import sys, os, time, atexit, optparse
# import the SWIG-wrapped main C++ functions
import main
import cc_main
# import a few SWIG-wrapped items (those that are likely to be used
# directly by user scripts) completely into this module for
# convenience
from main import simulate, SimLoopExitEvent
from cc_main import simulate, SimLoopExitEvent
# import the m5 compile options
import defines
@@ -58,6 +58,20 @@ def AddToPath(path):
sys.path.insert(1, path)
# The m5 module's pointer to the parsed options object
options = None
# User should call this function after calling parse_args() to pass
# parsed standard option values back into the m5 module for
# processing.
def setStandardOptions(_options):
# Set module global var
global options
options = _options
# tell C++ about output directory
cc_main.setOutputDir(options.outdir)
# Callback to set trace flags. Not necessarily the best way to do
# things in the long run (particularly if we change how these global
# options are handled).
@@ -67,28 +81,102 @@ def setTraceFlags(option, opt_str, value, parser):
def setTraceStart(option, opt_str, value, parser):
objects.Trace.start = value
def clearPCSymbol(option, opt_str, value, parser):
objects.ExecutionTrace.pc_symbol = False
def setTraceFile(option, opt_str, value, parser):
objects.Trace.file = value
def clearPrintCycle(option, opt_str, value, parser):
objects.ExecutionTrace.print_cycle = False
def usePCSymbol(option, opt_str, value, parser):
objects.ExecutionTrace.pc_symbol = value
def printCycle(option, opt_str, value, parser):
objects.ExecutionTrace.print_cycle = value
def printOp(option, opt_str, value, parser):
objects.ExecutionTrace.print_opclass = value
def printThread(option, opt_str, value, parser):
objects.ExecutionTrace.print_thread = value
def printEA(option, opt_str, value, parser):
objects.ExecutionTrace.print_effaddr = value
def printData(option, opt_str, value, parser):
objects.ExecutionTrace.print_data = value
def printFetchseq(option, opt_str, value, parser):
objects.ExecutionTrace.print_fetchseq = value
def printCpseq(option, opt_str, value, parser):
objects.ExecutionTrace.print_cpseq = value
def dumpOnExit(option, opt_str, value, parser):
objects.Trace.dump_on_exit = value
def debugBreak(option, opt_str, value, parser):
objects.Debug.break_cycles = value
def statsTextFile(option, opt_str, value, parser):
objects.Statistics.text_file = value
# Extra list to help for options that are true or false
TrueOrFalse = ['True', 'False']
TorF = "True | False"
# Standard optparse options. Need to be explicitly included by the
# user script when it calls optparse.OptionParser().
standardOptions = [
optparse.make_option("--outdir", type="string", default="."),
optparse.make_option("--traceflags", type="string", action="callback",
callback=setTraceFlags),
optparse.make_option("--tracestart", type="int", action="callback",
callback=setTraceStart),
optparse.make_option("--nopcsymbol", action="callback",
callback=clearPCSymbol,
help="Turn off printing PC symbols in trace output"),
optparse.make_option("--noprintcycle", action="callback",
callback=clearPrintCycle,
help="Turn off printing cycles in trace output"),
optparse.make_option("--tracefile", type="string", action="callback",
callback=setTraceFile),
optparse.make_option("--pcsymbol", type="choice", choices=TrueOrFalse,
default="True", metavar=TorF,
action="callback", callback=usePCSymbol,
help="Use PC symbols in trace output"),
optparse.make_option("--printcycle", type="choice", choices=TrueOrFalse,
default="True", metavar=TorF,
action="callback", callback=printCycle,
help="Print cycle numbers in trace output"),
optparse.make_option("--printopclass", type="choice",
choices=TrueOrFalse,
default="True", metavar=TorF,
action="callback", callback=printOp,
help="Print cycle numbers in trace output"),
optparse.make_option("--printthread", type="choice",
choices=TrueOrFalse,
default="True", metavar=TorF,
action="callback", callback=printThread,
help="Print thread number in trace output"),
optparse.make_option("--printeffaddr", type="choice",
choices=TrueOrFalse,
default="True", metavar=TorF,
action="callback", callback=printEA,
help="Print effective address in trace output"),
optparse.make_option("--printdata", type="choice",
choices=TrueOrFalse,
default="True", metavar=TorF,
action="callback", callback=printData,
help="Print result data in trace output"),
optparse.make_option("--printfetchseq", type="choice",
choices=TrueOrFalse,
default="True", metavar=TorF,
action="callback", callback=printFetchseq,
help="Print fetch sequence numbers in trace output"),
optparse.make_option("--printcpseq", type="choice",
choices=TrueOrFalse,
default="True", metavar=TorF,
action="callback", callback=printCpseq,
help="Print correct path sequence numbers in trace output"),
optparse.make_option("--dumponexit", type="choice",
choices=TrueOrFalse,
default="True", metavar=TorF,
action="callback", callback=dumpOnExit,
help="Dump trace buffer on exit"),
optparse.make_option("--debugbreak", type="int", metavar="CYCLE",
action="callback", callback=debugBreak,
help="Cycle to create a breakpoint"),
optparse.make_option("--statsfile", type="string", action="callback",
callback=statsTextFile, metavar="FILE",
help="Sets the output file for the statistics")
@@ -114,14 +202,14 @@ def resolveSimObject(name):
def instantiate(root):
config.ticks_per_sec = float(root.clock.frequency)
# ugly temporary hack to get output to config.ini
sys.stdout = file('config.ini', 'w')
sys.stdout = file(os.path.join(options.outdir, 'config.ini'), 'w')
root.print_ini()
sys.stdout.close() # close config.ini
sys.stdout = sys.__stdout__ # restore to original
main.loadIniFile(resolveSimObject) # load config.ini into C++
cc_main.loadIniFile(resolveSimObject) # load config.ini into C++
root.createCCObject()
root.connectPorts()
main.finalInit()
cc_main.finalInit()
noDot = True # temporary until we fix dot
if not noDot:
dot = pydot.Dot()
@@ -135,10 +223,10 @@ def instantiate(root):
# Export curTick to user script.
def curTick():
return main.cvar.curTick
return cc_main.cvar.curTick
# register our C++ exit callback function with Python
atexit.register(main.doExitCleanup)
atexit.register(cc_main.doExitCleanup)
# This import allows user scripts to reference 'm5.objects.Foo' after
# just doing an 'import m5' (without an 'import m5.objects'). May not

View File

@@ -30,7 +30,7 @@
import os, re, sys, types, inspect, copy
import m5
from m5 import panic
from m5 import panic, cc_main
from convert import *
from multidict import multidict
@@ -529,7 +529,7 @@ class SimObject(object):
def getCCObject(self):
if not self._ccObject:
self._ccObject = -1 # flag to catch cycles in recursion
self._ccObject = m5.main.createSimObject(self.path())
self._ccObject = cc_main.createSimObject(self.path())
elif self._ccObject == -1:
raise RuntimeError, "%s: recursive call to getCCObject()" \
% self.path()
@@ -1443,7 +1443,7 @@ class PortRef(object):
if self.ccConnected: # already done this
return
peer = self.peer
m5.main.connectPorts(self.simobj.getCCObject(), self.name, self.index,
cc_main.connectPorts(self.simobj.getCCObject(), self.name, self.index,
peer.simobj.getCCObject(), peer.name, peer.index)
self.ccConnected = True
peer.ccConnected = True

View File

@@ -2,8 +2,8 @@ from m5 import build_env
from m5.config import *
from BaseCPU import BaseCPU
class DerivAlphaFullCPU(BaseCPU):
type = 'DerivAlphaFullCPU'
class DerivAlphaO3CPU(BaseCPU):
type = 'DerivAlphaO3CPU'
activity = Param.Unsigned("Initial count")
numThreads = Param.Unsigned("number of HW thread contexts")

View File

@@ -0,0 +1,17 @@
from m5.config import *
class OpType(Enum):
vals = ['(null)', 'IntAlu', 'IntMult', 'IntDiv', 'FloatAdd',
'FloatCmp', 'FloatCvt', 'FloatMult', 'FloatDiv', 'FloatSqrt',
'MemRead', 'MemWrite', 'IprAccess', 'InstPrefetch']
class OpDesc(SimObject):
type = 'OpDesc'
issueLat = Param.Int(1, "cycles until another can be issued")
opClass = Param.OpType("type of operation")
opLat = Param.Int(1, "cycles until result is available")
class FUDesc(SimObject):
type = 'FUDesc'
count = Param.Int("number of these FU's available")
opList = VectorParam.OpDesc("operation classes for this FU type")

View File

@@ -168,7 +168,7 @@ sayHello(ostream &out)
}
extern "C" { void init_main(); }
extern "C" { void init_cc_main(); }
int
main(int argc, char **argv)
@@ -260,8 +260,8 @@ main(int argc, char **argv)
Py_Initialize();
PySys_SetArgv(argc, argv);
// initialize SWIG 'main' module
init_main();
// initialize SWIG 'cc_main' module
init_cc_main();
if (argc > 0) {
// extra arg(s): first is script file, remaining ones are args
@@ -299,6 +299,14 @@ main(int argc, char **argv)
Py_Finalize();
}
void
setOutputDir(const string &dir)
{
simout.setDirectory(dir);
}
IniFile inifile;
SimObject *