X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Finorder%2Finorder_dyn_inst.cc;h=b61beece2558fe1bdf8c76977810d5fb3a1acd7e;hb=39f314cc151b0a05ee0e654d52bad1c906fac668;hp=e9deb7625525bf84ea17dda5211d6d0d2e7b8501;hpb=e3d8d43b176d3a1eb69a5e5d16469d42292e514a;p=gem5.git diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index e9deb7625..b61beece2 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -31,69 +31,73 @@ #include #include -#include #include +#include #include "arch/faults.hh" +#include "base/bigint.hh" +#include "base/cp_annotate.hh" #include "base/cprintf.hh" #include "base/trace.hh" #include "config/the_isa.hh" -#include "cpu/exetrace.hh" #include "cpu/inorder/cpu.hh" #include "cpu/inorder/inorder_dyn_inst.hh" +#include "cpu/exetrace.hh" +#include "debug/InOrderDynInst.hh" #include "mem/request.hh" +#include "sim/full_system.hh" using namespace std; using namespace TheISA; using namespace ThePipeline; -InOrderDynInst::InOrderDynInst(TheISA::ExtMachInst machInst, - const TheISA::PCState &instPC, - const TheISA::PCState &_predPC, - InstSeqNum seq_num, InOrderCPU *cpu) - : staticInst(machInst, instPC.instAddr()), traceData(NULL), cpu(cpu) -{ - seqNum = seq_num; - - pc = instPC; - predPC = _predPC; - - initVars(); -} - InOrderDynInst::InOrderDynInst(InOrderCPU *cpu, InOrderThreadState *state, InstSeqNum seq_num, ThreadID tid, unsigned _asid) - : traceData(NULL), cpu(cpu) -{ - seqNum = seq_num; - thread = state; - threadNumber = tid; - asid = _asid; - initVars(); -} + : seqNum(seq_num), squashSeqNum(0), threadNumber(tid), asid(_asid), + virtProcNumber(0), staticInst(NULL), traceData(NULL), cpu(cpu), + thread(state), fault(NoFault), memData(NULL), loadData(0), + storeData(0), effAddr(0), physEffAddr(0), memReqFlags(0), + readyRegs(0), pc(0), predPC(0), memAddr(0), nextStage(0), + memTime(0), splitMemData(NULL), splitMemReq(NULL), totalSize(0), + split2ndSize(0), split2ndAddr(0), split2ndAccess(false), + split2ndDataPtr(NULL), split2ndFlags(0), splitInst(false), + splitFinishCnt(0), split2ndStoreDataPtr(NULL), splitInstSked(false), + inFrontEnd(true), frontSked(NULL), backSked(NULL), + squashingStage(0), predictTaken(false), procDelaySlotOnMispred(false), + fetchMemReq(NULL), dataMemReq(NULL), instEffAddr(0), eaCalcDone(false), + lqIdx(0), sqIdx(0), instListIt(NULL), onInstList(false) +{ + for(int i = 0; i < MaxInstSrcRegs; i++) { + _readySrcRegIdx[i] = false; + _srcRegIdx[i] = 0; + } -InOrderDynInst::InOrderDynInst(StaticInstPtr &_staticInst) - : seqNum(0), staticInst(_staticInst), traceData(NULL) -{ - initVars(); -} + for(int j = 0; j < MaxInstDestRegs; j++) { + _destRegIdx[j] = 0; + _prevDestRegIdx[j] = 0; + } + + ++instcount; + DPRINTF(InOrderDynInst, "DynInst: [tid:%i] [sn:%lli] Instruction created." + " (active insts: %i)\n", threadNumber, seqNum, instcount); -InOrderDynInst::InOrderDynInst() - : seqNum(0), traceData(NULL), cpu(cpu) -{ - initVars(); } int InOrderDynInst::instcount = 0; +int +InOrderDynInst::cpuId() +{ + return cpu->cpuId(); +} void -InOrderDynInst::setMachInst(ExtMachInst machInst) +InOrderDynInst::setStaticInst(StaticInstPtr si) { - staticInst = StaticInst::decode(machInst, pc.instAddr()); + staticInst = si; for (int i = 0; i < this->staticInst->numDestRegs(); i++) { _destRegIdx[i] = this->staticInst->destRegIdx(i); @@ -126,14 +130,10 @@ InOrderDynInst::initVars() nextStage = 0; - for(int i = 0; i < MaxInstDestRegs; i++) - instResult[i].val.integer = 0; - status.reset(); memAddrReady = false; eaCalcDone = false; - memOpDone = false; predictTaken = false; procDelaySlotOnMispred = false; @@ -164,16 +164,10 @@ InOrderDynInst::initVars() } // Update Instruction Count for this instruction - ++instcount; 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); } void @@ -185,24 +179,12 @@ InOrderDynInst::resetInstCount() InOrderDynInst::~InOrderDynInst() { - if (fetchMemReq != 0x0) { - delete fetchMemReq; - fetchMemReq = NULL; - } - - if (dataMemReq != 0x0) { - delete dataMemReq; - dataMemReq = NULL; - } - - if (traceData) { + if (traceData) delete traceData; - } - if (splitMemData) { + if (splitMemData) delete [] splitMemData; - } - + fault = NoFault; --instcount; @@ -288,12 +270,27 @@ InOrderDynInst::memAccess() } -#if FULL_SYSTEM - Fault InOrderDynInst::hwrei() { - panic("InOrderDynInst: hwrei: unimplemented\n"); +#if THE_ISA == ALPHA_ISA + // Can only do a hwrei when in pal mode. + if (!(this->instAddr() & 0x3)) + return new AlphaISA::UnimplementedOpcodeFault; + + // Set the next PC based on the value of the EXC_ADDR IPR. + AlphaISA::PCState pc = this->pcState(); + pc.npc(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, + this->threadNumber)); + this->pcState(pc); + if (CPA::available()) { + ThreadContext *tc = this->cpu->tcBase(this->threadNumber); + CPA::cpa()->swAutoBegin(tc, this->nextInstAddr()); + } + + // Tell CPU to clear any state it needs to if a hwrei is taken. + this->cpu->hwrei(this->threadNumber); +#endif return NoFault; } @@ -313,13 +310,46 @@ InOrderDynInst::simPalCheck(int palFunc) #endif return this->cpu->simPalCheck(palFunc, this->threadNumber); } -#else + void InOrderDynInst::syscall(int64_t callnum) { - cpu->syscall(callnum, this->threadNumber); + if (FullSystem) + panic("Syscall emulation isn't available in FS mode.\n"); + + syscallNum = callnum; + cpu->syscallContext(NoFault, this->threadNumber, this); } + +void +InOrderDynInst::setSquashInfo(unsigned stage_num) +{ + squashingStage = stage_num; + + // If it's a fault, then we need to squash + // the faulting instruction too. Squash + // functions squash above a seqNum, so we + // decrement here for that case + if (fault != NoFault) { + squashSeqNum = seqNum - 1; + return; + } else + squashSeqNum = seqNum; + +#if ISA_HAS_DELAY_SLOT + if (staticInst && isControl()) { + TheISA::PCState nextPC = pc; + TheISA::advancePC(nextPC, staticInst); + + // Check to see if we should squash after the + // branch or after a branch delay slot. + if (pc.nextInstAddr() == pc.instAddr() + sizeof(MachInst)) + squashSeqNum = seqNum + 1; + else + squashSeqNum = seqNum; + } #endif +} void InOrderDynInst::releaseReq(ResourceRequest* req) @@ -345,39 +375,48 @@ InOrderDynInst::releaseReq(ResourceRequest* req) void InOrderDynInst::setIntSrc(int idx, uint64_t val) { - DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Source Value %i being set " + DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] [src:%i] Int being set " "to %#x.\n", threadNumber, seqNum, idx, val); - instSrc[idx].integer = val; + instSrc[idx].intVal = val; } /** Records an fp register being set to a value. */ void InOrderDynInst::setFloatSrc(int idx, FloatReg val) { - instSrc[idx].dbl = val; + instSrc[idx].fpVal.f = val; + DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] [src:%i] FP being set " + "to %x, %08f...%08f\n", threadNumber, seqNum, idx, + instSrc[idx].fpVal.i, instSrc[idx].fpVal.f, val); } /** Records an fp register being set to an integer value. */ void -InOrderDynInst::setFloatRegBitsSrc(int idx, uint64_t val) +InOrderDynInst::setFloatRegBitsSrc(int idx, FloatRegBits val) { - instSrc[idx].integer = val; + instSrc[idx].fpVal.i = val; + DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] [src:%i] FPBits being set " + "to %x, %08f...%x\n", threadNumber, seqNum, idx, + instSrc[idx].fpVal.i, instSrc[idx].fpVal.f, val); } /** Reads a integer register. */ IntReg 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); - return instSrc[idx].integer; + DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] [src:%i] IntVal read as %#x.\n", + threadNumber, seqNum, idx, instSrc[idx].intVal); + return instSrc[idx].intVal; } /** Reads a FP register. */ FloatReg InOrderDynInst::readFloatRegOperand(const StaticInst *si, int idx) { - return instSrc[idx].dbl; + DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] [src:%i] FPVal being read " + "as %x, %08f.\n", threadNumber, seqNum, idx, + instSrc[idx].fpVal.i, instSrc[idx].fpVal.f); + return instSrc[idx].fpVal.f; } @@ -385,7 +424,10 @@ InOrderDynInst::readFloatRegOperand(const StaticInst *si, int idx) FloatRegBits InOrderDynInst::readFloatRegOperandBits(const StaticInst *si, int idx) { - return instSrc[idx].integer; + DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] [src:%i] FPBits being read " + "as %x, %08f.\n", threadNumber, seqNum, idx, + instSrc[idx].fpVal.i, instSrc[idx].fpVal.f); + return instSrc[idx].fpVal.i; } /** Reads a miscellaneous register. */ @@ -404,8 +446,8 @@ InOrderDynInst::readMiscRegOperand(const StaticInst *si, int idx) { 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; + instSrc[idx].intVal); + return instSrc[idx].intVal; } @@ -417,7 +459,7 @@ InOrderDynInst::setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) { instResult[idx].type = Integer; - instResult[idx].val.integer = val; + instResult[idx].res.intVal = val; instResult[idx].tick = curTick(); DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Misc Reg. Operand %i " @@ -447,7 +489,7 @@ void InOrderDynInst::setIntRegOperand(const StaticInst *si, int idx, IntReg val) { instResult[idx].type = Integer; - instResult[idx].val.integer = val; + instResult[idx].res.intVal = val; instResult[idx].tick = curTick(); DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Result Int Reg. %i " @@ -459,13 +501,13 @@ InOrderDynInst::setIntRegOperand(const StaticInst *si, int idx, IntReg val) void InOrderDynInst::setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { - instResult[idx].val.dbl = val; instResult[idx].type = Float; + instResult[idx].res.fpVal.f = 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); + DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Result Float Reg. %i " + "being set to %#x, %08f (result-tick:%i).\n", + threadNumber, seqNum, idx, val, val, instResult[idx].tick); } /** Sets a FP register as a integer. */ @@ -473,11 +515,11 @@ void InOrderDynInst::setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val) { - instResult[idx].type = Integer; - instResult[idx].val.integer = val; + instResult[idx].type = FloatBits; + instResult[idx].res.fpVal.i = val; instResult[idx].tick = curTick(); - DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting Result Float Reg. %i " + DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Result Float Reg. Bits %i " "being set to %#x (result-tick:%i).\n", threadNumber, seqNum, idx, val, instResult[idx].tick); } @@ -518,136 +560,17 @@ InOrderDynInst::deallocateContext(int thread_num) } Fault -InOrderDynInst::readBytes(Addr addr, uint8_t *data, - unsigned size, unsigned flags) +InOrderDynInst::readMem(Addr addr, uint8_t *data, + unsigned size, unsigned flags) { return cpu->read(this, addr, data, size, flags); } -template -inline Fault -InOrderDynInst::read(Addr addr, T &data, unsigned flags) -{ - if (traceData) { - traceData->setAddr(addr); - traceData->setData(data); - } - Fault fault = readBytes(addr, (uint8_t *)&data, sizeof(T), flags); - data = TheISA::gtoh(data); - if (traceData) - traceData->setData(data); - return fault; -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -template -Fault -InOrderDynInst::read(Addr addr, uint64_t &data, unsigned flags); - -template -Fault -InOrderDynInst::read(Addr addr, uint32_t &data, unsigned flags); - -template -Fault -InOrderDynInst::read(Addr addr, uint16_t &data, unsigned flags); - -template -Fault -InOrderDynInst::read(Addr addr, uint8_t &data, unsigned flags); - -#endif //DOXYGEN_SHOULD_SKIP_THIS - -template<> -Fault -InOrderDynInst::read(Addr addr, double &data, unsigned flags) -{ - return read(addr, *(uint64_t*)&data, flags); -} - -template<> -Fault -InOrderDynInst::read(Addr addr, float &data, unsigned flags) -{ - return read(addr, *(uint32_t*)&data, flags); -} - -template<> -Fault -InOrderDynInst::read(Addr addr, int32_t &data, unsigned flags) -{ - return read(addr, (uint32_t&)data, flags); -} - -Fault -InOrderDynInst::writeBytes(uint8_t *data, unsigned size, - Addr addr, unsigned flags, uint64_t *res) -{ - assert(sizeof(storeData) >= size); - memcpy(&storeData, data, size); - return cpu->write(this, (uint8_t *)&storeData, size, addr, flags, res); -} - -template -inline Fault -InOrderDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res) -{ - storeData = data; - - DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting store data to %#x.\n", - threadNumber, seqNum, storeData); - if (traceData) { - traceData->setAddr(addr); - traceData->setData(data); - } - storeData = TheISA::htog(data); - return writeBytes((uint8_t*)&data, sizeof(T), addr, flags, res); -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS -template -Fault -InOrderDynInst::write(uint64_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -InOrderDynInst::write(uint32_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -InOrderDynInst::write(uint16_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -InOrderDynInst::write(uint8_t data, Addr addr, - unsigned flags, uint64_t *res); - -#endif //DOXYGEN_SHOULD_SKIP_THIS - -template<> -Fault -InOrderDynInst::write(double data, Addr addr, unsigned flags, uint64_t *res) -{ - return write(*(uint64_t*)&data, addr, flags, res); -} - -template<> -Fault -InOrderDynInst::write(float data, Addr addr, unsigned flags, uint64_t *res) -{ - return write(*(uint32_t*)&data, addr, flags, res); -} - - -template<> Fault -InOrderDynInst::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) +InOrderDynInst::writeMem(uint8_t *data, unsigned size, + Addr addr, unsigned flags, uint64_t *res) { - return write((uint32_t)data, addr, flags, res); + return cpu->write(this, data, size, addr, flags, res); }