X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fozone%2Ffront_end_impl.hh;h=88413692761484b4dcf82403c931f4a75139530a;hb=69fc2af00600ced942d81dba082d9780e5325c9e;hp=9da9373203ade603639558152bb7081c074be299;hpb=43245d9c2f3986430c1fbc4a09ee90096f6d3f30;p=gem5.git diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 9da937320..884136927 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -28,11 +28,12 @@ * Authors: Kevin Lim */ -#include "config/use_checker.hh" - -#include "arch/faults.hh" +#include "sim/faults.hh" #include "arch/isa_traits.hh" +#include "arch/utility.hh" #include "base/statistics.hh" +#include "config/the_isa.hh" +#include "config/use_checker.hh" #include "cpu/thread_context.hh" #include "cpu/exetrace.hh" #include "cpu/ozone/front_end.hh" @@ -58,7 +59,7 @@ template void FrontEnd::IcachePort::recvFunctional(PacketPtr pkt) { - panic("FrontEnd doesn't expect recvFunctional callback!"); + warn("FrontEnd doesn't update state from functional calls"); } template @@ -73,7 +74,7 @@ FrontEnd::IcachePort::recvStatusChange(Status status) template bool -FrontEnd::IcachePort::recvTiming(Packet *pkt) +FrontEnd::IcachePort::recvTiming(PacketPtr pkt) { fe->processCacheCompletion(pkt); return true; @@ -90,9 +91,10 @@ template FrontEnd::FrontEnd(Params *params) : branchPred(params), icachePort(this), - mem(params->mem), + numInstsReady(params->frontEndLatency, 0), instBufferSize(0), maxInstBufferSize(params->maxInstBufferSize), + latency(params->frontEndLatency), width(params->frontEndWidth), freeRegs(params->numPhysicalRegs), numPhysRegs(params->numPhysicalRegs), @@ -325,6 +327,18 @@ FrontEnd::tick() if (switchedOut) return; + for (int insts_to_queue = numInstsReady[-latency]; + !instBuffer.empty() && insts_to_queue; + --insts_to_queue) + { + DPRINTF(FE, "Transferring instruction [sn:%lli] to the feBuffer\n", + instBuffer.front()->seqNum); + feBuffer.push_back(instBuffer.front()); + instBuffer.pop_front(); + } + + numInstsReady.advance(); + // @todo: Maybe I want to just have direct communication... if (fromCommit->doneSeqNum) { branchPred.update(fromCommit->doneSeqNum, 0); @@ -338,8 +352,8 @@ FrontEnd::tick() cacheBlkValid = true; status = Running; - if (barrierInst) - status = SerializeBlocked; +// if (barrierInst) +// status = SerializeBlocked; if (freeRegs <= 0) status = RenameBlocked; checkBE(); @@ -413,11 +427,12 @@ FrontEnd::tick() // latency instBuffer.push_back(inst); ++instBufferSize; + numInstsReady[0]++; ++num_inst; #if FULL_SYSTEM if (inst->isQuiesce()) { - warn("%lli: Quiesce instruction encountered, halting fetch!", curTick); +// warn("%lli: Quiesce instruction encountered, halting fetch!", curTick); status = QuiescePending; break; } @@ -447,15 +462,10 @@ Fault FrontEnd::fetchCacheLine() { // Read a cache line, based on the current PC. -#if FULL_SYSTEM - // Flag to say whether or not address is physical addr. - unsigned flags = cpu->inPalMode(PC) ? PHYSICAL : 0; -#else - unsigned flags = 0; -#endif // FULL_SYSTEM Fault fault = NoFault; - if (interruptPending && flags == 0) { + //AlphaDep + if (interruptPending && (PC & 0x3)) { return fault; } @@ -466,18 +476,18 @@ FrontEnd::fetchCacheLine() // Setup the memReq to do a read of the first isntruction's address. // Set the appropriate read size and flags as well. - memReq = new Request(0, fetch_PC, cacheBlkSize, flags, - fetch_PC, cpu->readCpuId(), 0); + memReq = new Request(0, fetch_PC, cacheBlkSize, 0, + PC, cpu->thread->contextId()); // Translate the instruction request. - fault = cpu->translateInstReq(memReq, thread); + fault = cpu->itb->translateAtomic(memReq, thread, false, true); // Now do the timing access to see whether or not the instruction // exists within the cache. if (fault == NoFault) { #if 0 if (cpu->system->memctrl->badaddr(memReq->paddr) || - memReq->flags & UNCACHEABLE) { + memReq->isUncacheable()) { DPRINTF(FE, "Fetch: Bad address %#x (hopefully on a " "misspeculating path!", memReq->paddr); @@ -571,10 +581,10 @@ FrontEnd::processBarriers(DynInstPtr &inst) // Change status over to SerializeBlocked so that other stages know // what this is blocked on. - status = SerializeBlocked; +// status = SerializeBlocked; - barrierInst = inst; - return true; +// barrierInst = inst; +// return true; } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) && !inst->isSerializeHandled()) { DPRINTF(FE, "Serialize after instruction encountered.\n"); @@ -619,6 +629,7 @@ FrontEnd::handleFault(Fault &fault) instruction->fault = fault; instruction->setCanIssue(); instBuffer.push_back(instruction); + numInstsReady[0]++; ++instBufferSize; } @@ -648,6 +659,21 @@ FrontEnd::squash(const InstSeqNum &squash_num, const Addr &next_PC, freeRegs+= inst->numDestRegs(); } + while (!feBuffer.empty() && + feBuffer.back()->seqNum > squash_num) { + DynInstPtr inst = feBuffer.back(); + + DPRINTF(FE, "Squashing instruction [sn:%lli] PC %#x\n", + inst->seqNum, inst->readPC()); + + inst->clearDependents(); + + feBuffer.pop_back(); + --instBufferSize; + + freeRegs+= inst->numDestRegs(); + } + // Copy over rename table from the back end. renameTable.copyFrom(backEnd->renameTable); @@ -665,12 +691,12 @@ FrontEnd::squash(const InstSeqNum &squash_num, const Addr &next_PC, DPRINTF(FE, "Squashing outstanding Icache access.\n"); memReq = NULL; } - +/* if (status == SerializeBlocked) { assert(barrierInst->seqNum > squash_num); barrierInst = NULL; } - +*/ // Unless this squash originated from the front end, we're probably // in running mode now. // Actually might want to make this latency dependent. @@ -682,13 +708,22 @@ template typename Impl::DynInstPtr FrontEnd::getInst() { - if (instBufferSize == 0) { + if (feBuffer.empty()) { return NULL; } - DynInstPtr inst = instBuffer.front(); + DynInstPtr inst = feBuffer.front(); + + if (inst->isSerializeBefore() || inst->isIprAccess()) { + DPRINTF(FE, "Back end is getting a serialize before inst\n"); + if (!backEnd->robEmpty()) { + DPRINTF(FE, "Rob is not empty yet, not returning inst\n"); + return NULL; + } + inst->clearSerializeBefore(); + } - instBuffer.pop_front(); + feBuffer.pop_front(); --instBufferSize; @@ -783,11 +818,11 @@ FrontEnd::updateStatus() } if (status == BEBlocked && !be_block) { - if (barrierInst) { - status = SerializeBlocked; - } else { +// if (barrierInst) { +// status = SerializeBlocked; +// } else { status = Running; - } +// } ret_val = true; } return ret_val; @@ -809,6 +844,7 @@ template typename Impl::DynInstPtr FrontEnd::getInstFromCacheline() { +/* if (status == SerializeComplete) { DynInstPtr inst = barrierInst; status = Running; @@ -816,7 +852,7 @@ FrontEnd::getInstFromCacheline() inst->clearSerializeBefore(); return inst; } - +*/ InstSeqNum inst_seq; MachInst inst; // @todo: Fix this magic number used here to handle word offset (and @@ -841,7 +877,11 @@ FrontEnd::getInstFromCacheline() // Get the instruction from the array of the cache line. inst = htog(*reinterpret_cast(&cacheData[offset])); +#if THE_ISA == ALPHA_ISA ExtMachInst decode_inst = TheISA::makeExtMI(inst, PC); +#elif THE_ISA == SPARC_ISA + ExtMachInst decode_inst = TheISA::makeExtMI(inst, tc); +#endif // Create a new DynInst from the instruction fetched. DynInstPtr instruction = new DynInst(decode_inst, PC, PC+sizeof(MachInst), @@ -854,9 +894,9 @@ FrontEnd::getInstFromCacheline() instruction->staticInst->disassemble(PC)); instruction->traceData = - Trace::getInstRecord(curTick, tc, cpu, + Trace::getInstRecord(curTick, tc, instruction->staticInst, - instruction->readPC(), 0); + instruction->readPC()); // Increment stat of fetched instructions. ++fetchedInsts; @@ -931,6 +971,7 @@ FrontEnd::doSwitchOut() squash(0, 0); instBuffer.clear(); instBufferSize = 0; + feBuffer.clear(); status = Idle; }