#include <string>
#include <sstream>
+#include "arch/faults.hh"
#include "base/cprintf.hh"
#include "base/trace.hh"
-
-#include "arch/faults.hh"
+#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
-#include "mem/request.hh"
-
-#include "cpu/inorder/inorder_dyn_inst.hh"
#include "cpu/inorder/cpu.hh"
+#include "cpu/inorder/inorder_dyn_inst.hh"
+#include "mem/request.hh"
using namespace std;
using namespace TheISA;
}
InOrderDynInst::InOrderDynInst(InOrderCPU *cpu,
- InOrderThreadState *state,
- InstSeqNum seq_num,
- unsigned tid)
+ InOrderThreadState *state,
+ InstSeqNum seq_num,
+ ThreadID tid,
+ unsigned _asid)
: traceData(NULL), cpu(cpu)
{
seqNum = seq_num;
thread = state;
threadNumber = tid;
+ asid = _asid;
initVars();
}
InOrderDynInst::InOrderDynInst(StaticInstPtr &_staticInst)
- : staticInst(_staticInst), traceData(NULL)
+ : seqNum(0), staticInst(_staticInst), traceData(NULL)
{
- seqNum = 0;
initVars();
}
InOrderDynInst::InOrderDynInst()
- : traceData(NULL), cpu(cpu)
+ : seqNum(0), traceData(NULL), cpu(cpu)
{
- seqNum = 0;
initVars();
}
void
InOrderDynInst::initVars()
{
- req = NULL;
+ fetchMemReq = NULL;
+ dataMemReq = NULL;
+ splitMemData = NULL;
+ split2ndAddr = 0;
+ split2ndAccess = false;
+ splitInst = false;
+ splitInstSked = false;
+ splitFinishCnt = 0;
+
effAddr = 0;
physEffAddr = 0;
// Update Instruction Count for this instruction
++instcount;
- if (instcount > 500) {
+ if (instcount > 100) {
fatal("Number of Active Instructions in CPU is too high. "
"(Not Dereferencing Ptrs. Correctly?)\n");
}
- DPRINTF(InOrderDynInst, "DynInst: [tid:%i] [sn:%lli] Instruction created. (active insts: %i)\n",
- threadNumber, seqNum, instcount);
+ DPRINTF(InOrderDynInst, "DynInst: [tid:%i] [sn:%lli] Instruction created."
+ " (active insts: %i)\n", threadNumber, seqNum, instcount);
+}
-#ifdef DEBUG
- cpu->snList.insert(seqNum);
-#endif
+void
+InOrderDynInst::resetInstCount()
+{
+ instcount = 0;
}
InOrderDynInst::~InOrderDynInst()
{
- if (req) {
- delete req;
+ if (fetchMemReq != 0x0) {
+ delete fetchMemReq;
+ fetchMemReq = NULL;
+ }
+
+ if (dataMemReq != 0x0) {
+ delete dataMemReq;
+ dataMemReq = NULL;
}
if (traceData) {
delete traceData;
}
+ if (splitMemData) {
+ delete [] splitMemData;
+ }
+
fault = NoFault;
--instcount;
deleteStages();
- DPRINTF(InOrderDynInst, "DynInst: [tid:%i] [sn:%lli] Instruction destroyed. (active insts: %i)\n",
- threadNumber, seqNum, instcount);
-#ifdef DEBUG
- cpu->snList.erase(seqNum);
-#endif
+ DPRINTF(InOrderDynInst, "DynInst: [tid:%i] [sn:%lli] Instruction destroyed"
+ " (active insts: %i)\n", threadNumber, seqNum, instcount);
}
void
return this->fault;
}
+Fault
+InOrderDynInst::calcEA()
+{
+ this->fault = this->staticInst->eaComp(this, this->traceData);
+ return this->fault;
+}
+
Fault
InOrderDynInst::initiateAcc()
{
}
Fault
-InOrderDynInst::calcEA()
+InOrderDynInst::memAccess()
{
- return staticInst->eaCompInst()->execute(this, this->traceData);
+ return initiateAcc();
}
+
+#if FULL_SYSTEM
+
Fault
-InOrderDynInst::memAccess()
+InOrderDynInst::hwrei()
+{
+ panic("InOrderDynInst: hwrei: unimplemented\n");
+ return NoFault;
+}
+
+
+void
+InOrderDynInst::trap(Fault fault)
{
- //return staticInst->memAccInst()->execute(this, this->traceData);
- return initiateAcc( );
+ this->cpu->trap(fault, this->threadNumber);
}
+
+bool
+InOrderDynInst::simPalCheck(int palFunc)
+{
+#if THE_ISA != ALPHA_ISA
+ panic("simPalCheck called, but PAL only exists in Alpha!\n");
+#endif
+ return this->cpu->simPalCheck(palFunc, this->threadNumber);
+}
+#else
void
InOrderDynInst::syscall(int64_t callnum)
{
cpu->syscall(callnum, this->threadNumber);
}
+#endif
void
InOrderDynInst::prefetch(Addr addr, unsigned flags)
{
- // This is the "functional" implementation of prefetch. Not much
- // happens here since prefetches don't affect the architectural
- // state.
-/*
- // Generate a MemReq so we can translate the effective address.
- MemReqPtr req = new MemReq(addr, thread->getXCProxy(), 1, flags);
- req->asid = asid;
-
- // Prefetches never cause faults.
- fault = NoFault;
-
- // note this is a local, not InOrderDynInst::fault
- Fault trans_fault = cpu->translateDataReadReq(req);
-
- if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) {
- // It's a valid address to cacheable space. Record key MemReq
- // parameters so we can generate another one just like it for
- // the timing access without calling translate() again (which
- // might mess up the TLB).
- effAddr = req->vaddr;
- physEffAddr = req->paddr;
- memReqFlags = req->flags;
- } else {
- // Bogus address (invalid or uncacheable space). Mark it by
- // setting the eff_addr to InvalidAddr.
- effAddr = physEffAddr = MemReq::inval_addr;
- }
-
- if (traceData) {
- traceData->setAddr(addr);
- }
-*/
+ cpu->prefetch(this);
}
void
InOrderDynInst::writeHint(Addr addr, int size, unsigned flags)
{
- // Not currently supported.
+ cpu->writeHint(this);
}
/**
while(list_it != list_end) {
if((*list_it)->getResIdx() == req->getResIdx() &&
(*list_it)->getSlot() == req->getSlot()) {
- DPRINTF(InOrderDynInst, "[tid:%u]: [sn:%i] Done with request to %s.\n",
- threadNumber, seqNum, req->res->name());
+ DPRINTF(InOrderDynInst, "[tid:%u]: [sn:%i] Done with request "
+ "to %s.\n", threadNumber, seqNum, req->res->name());
reqList.erase(list_it);
return;
}
void
InOrderDynInst::setIntSrc(int idx, uint64_t val)
{
- DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Source Value %i being set to %#x.\n",
- threadNumber, seqNum, idx, val);
+ DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Source Value %i being set "
+ "to %#x.\n", threadNumber, seqNum, idx, val);
instSrc[idx].integer = val;
}
/** Records an fp register being set to a value. */
void
-InOrderDynInst::setFloatSrc(int idx, FloatReg val, int width)
+InOrderDynInst::setFloatSrc(int idx, FloatReg val)
{
- if (width == 32)
- instSrc[idx].fp = val;
- else if (width == 64)
- instSrc[idx].dbl = val;
- else
- panic("Unsupported width!");
+ instSrc[idx].dbl = val;
}
/** Records an fp register being set to an integer value. */
/** Reads a integer register. */
IntReg
-InOrderDynInst::readIntRegOperand(const StaticInst *si, int idx, unsigned tid)
+InOrderDynInst::readIntRegOperand(const StaticInst *si, int idx, ThreadID tid)
{
DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Source Value %i read as %#x.\n",
threadNumber, seqNum, idx, instSrc[idx].integer);
/** Reads a FP register. */
FloatReg
-InOrderDynInst::readFloatRegOperand(const StaticInst *si, int idx, int width)
+InOrderDynInst::readFloatRegOperand(const StaticInst *si, int idx)
{
- return instSrc[idx].fp;
+ return instSrc[idx].dbl;
}
/** Reads a FP register as a integer. */
FloatRegBits
-InOrderDynInst::readFloatRegOperandBits(const StaticInst *si, int idx, int width)
+InOrderDynInst::readFloatRegOperandBits(const StaticInst *si, int idx)
{
return instSrc[idx].integer;
}
MiscReg
InOrderDynInst::readMiscRegOperandNoEffect(const StaticInst *si, int idx)
{
- int reg = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
- return cpu->readMiscRegNoEffect(reg, this->threadNumber);
+ DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Misc. Reg Source Value %i"
+ " read as %#x.\n", threadNumber, seqNum, idx,
+ instSrc[idx].integer);
+ return instSrc[idx].integer;
}
/** Reads a misc. register, including any side-effects the read
MiscReg
InOrderDynInst::readMiscRegOperand(const StaticInst *si, int idx)
{
- int reg = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
- return this->cpu->readMiscReg(reg, this->threadNumber);
+ // For In-Order, the side-effect of reading a register happens
+ // when explicitly executing a "ReadSrc" command. This simply returns
+ // a value.
+ return readMiscRegOperandNoEffect(si, idx);
}
/** Sets a misc. register. */
void
-InOrderDynInst::setMiscRegOperandNoEffect(const StaticInst * si, int idx, const MiscReg &val)
+InOrderDynInst::setMiscRegOperandNoEffect(const StaticInst * si, int idx,
+ const MiscReg &val)
{
- instResult[si->destRegIdx(idx)].val.integer = val;
- instResult[si->destRegIdx(idx)].tick = curTick;
+ instResult[idx].type = Integer;
+ instResult[idx].val.integer = val;
+ instResult[idx].tick = curTick;
- this->cpu->setMiscRegNoEffect(
- si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
- val, this->threadNumber);
+ DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Misc Reg. Operand %i "
+ "being set to %#x.\n", threadNumber, seqNum, idx, val);
}
/** Sets a misc. register, including any side-effects the write
InOrderDynInst::setMiscRegOperand(const StaticInst *si, int idx,
const MiscReg &val)
{
- instResult[si->destRegIdx(idx)].val.integer = val;
- instResult[si->destRegIdx(idx)].tick = curTick;
-
- this->cpu->setMiscReg(
- si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
- val, this->threadNumber);
+ // For In-Order, the side-effect of setting a register happens
+ // when explicitly writing back the register value. This
+ // simply maintains the operand value.
+ setMiscRegOperandNoEffect(si, idx, val);
}
MiscReg
-InOrderDynInst::readRegOtherThread(unsigned reg_idx, int tid)
+InOrderDynInst::readRegOtherThread(unsigned reg_idx, ThreadID tid)
{
if (tid == -1) {
tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
void
InOrderDynInst::setIntRegOperand(const StaticInst *si, int idx, IntReg val)
{
+ instResult[idx].type = Integer;
instResult[idx].val.integer = val;
instResult[idx].tick = curTick;
+
+ DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Result Int Reg. %i "
+ "being set to %#x (result-tick:%i).\n",
+ threadNumber, seqNum, idx, val, instResult[idx].tick);
}
/** Sets a FP register. */
void
-InOrderDynInst::setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, int width)
+InOrderDynInst::setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
{
- if (width == 32)
- instResult[idx].val.fp = val;
- else if (width == 64)
- instResult[idx].val.dbl = val;
- else
- panic("Unsupported Floating Point Width!");
-
+ instResult[idx].val.dbl = val;
+ instResult[idx].type = Float;
instResult[idx].tick = curTick;
+
+ DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Result Float Reg. %i "
+ "being set to %#x (result-tick:%i).\n",
+ threadNumber, seqNum, idx, val, instResult[idx].tick);
}
/** Sets a FP register as a integer. */
void
InOrderDynInst::setFloatRegOperandBits(const StaticInst *si, int idx,
- FloatRegBits val, int width)
+ FloatRegBits val)
{
+ instResult[idx].type = Integer;
instResult[idx].val.integer = val;
instResult[idx].tick = curTick;
+
+ DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Result Float Reg. %i "
+ "being set to %#x (result-tick:%i).\n",
+ threadNumber, seqNum, idx, val, instResult[idx].tick);
}
/** Sets a misc. register. */
}
void
-InOrderDynInst::setRegOtherThread(unsigned reg_idx, const MiscReg &val, int tid)
+InOrderDynInst::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
+ ThreadID tid)
{
- if (tid == -1) {
+ if (tid == InvalidThreadID) {
tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
}
this->cpu->deallocateContext(thread_num);
}
-void
-InOrderDynInst::enableVirtProcElement(unsigned vpe)
-{
- this->cpu->enableVirtProcElement(vpe);
-}
-
-void
-InOrderDynInst::disableVirtProcElement(unsigned vpe)
-{
- this->cpu->disableVirtProcElement(threadNumber, vpe);
-}
-
-void
-InOrderDynInst::enableMultiThreading(unsigned vpe)
-{
- this->cpu->enableMultiThreading(vpe);
-}
-
-void
-InOrderDynInst::disableMultiThreading(unsigned vpe)
-{
- this->cpu->disableMultiThreading(threadNumber, vpe);
-}
-
-void
-InOrderDynInst::setThreadRescheduleCondition(uint32_t cond)
-{
- this->cpu->setThreadRescheduleCondition(cond);
-}
-
template<class T>
inline Fault
InOrderDynInst::read(Addr addr, T &data, unsigned flags)
{
- return cpu->read(this);
+ if (traceData) {
+ traceData->setAddr(addr);
+ traceData->setData(data);
+ }
+
+ return cpu->read(this, addr, data, flags);
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
inline Fault
InOrderDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
- //memcpy(memData, gtoh(data), sizeof(T));
+ if (traceData) {
+ traceData->setAddr(addr);
+ traceData->setData(data);
+ }
+
storeData = data;
DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting store data to %#x.\n",
- threadNumber, seqNum, memData);
- return cpu->write(this);
+ threadNumber, seqNum, storeData);
+ return cpu->write(this, data, addr, flags, res);
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
return hash;
}
-typedef m5::hash_map<const InOrderDynInst *, const InOrderDynInst *, MyHashFunc>
+typedef m5::hash_map<const InOrderDynInst *, const InOrderDynInst *,
+ MyHashFunc>
my_hash_t;
my_hash_t thishash;
#endif
-
-#ifdef DEBUG
-
-void
-InOrderDynInst::dumpSNList()
-{
- std::set<InstSeqNum>::iterator sn_it = cpu->snList.begin();
-
- int count = 0;
- while (sn_it != cpu->snList.end()) {
- cprintf("%i: [sn:%lli] not destroyed\n", count, (*sn_it));
- count++;
- sn_it++;
- }
-}
-#endif
-