X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fozone%2Ffront_end_impl.hh;h=88413692761484b4dcf82403c931f4a75139530a;hb=69fc2af00600ced942d81dba082d9780e5325c9e;hp=8a15378a76ca49a97cd35ca847a7be21d0ccb0b2;hpb=76708a9a6c85ef88259e849220bde511e356fcf8;p=gem5.git diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 8a15378a7..884136927 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -28,12 +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" @@ -59,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 @@ -74,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; @@ -91,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), @@ -326,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); @@ -339,8 +352,8 @@ FrontEnd::tick() cacheBlkValid = true; status = Running; - if (barrierInst) - status = SerializeBlocked; +// if (barrierInst) +// status = SerializeBlocked; if (freeRegs <= 0) status = RenameBlocked; checkBE(); @@ -414,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; } @@ -448,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; } @@ -467,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); @@ -572,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"); @@ -620,6 +629,7 @@ FrontEnd::handleFault(Fault &fault) instruction->fault = fault; instruction->setCanIssue(); instBuffer.push_back(instruction); + numInstsReady[0]++; ++instBufferSize; } @@ -649,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); @@ -666,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. @@ -683,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; @@ -784,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; @@ -810,6 +844,7 @@ template typename Impl::DynInstPtr FrontEnd::getInstFromCacheline() { +/* if (status == SerializeComplete) { DynInstPtr inst = barrierInst; status = Running; @@ -817,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 @@ -842,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), @@ -932,6 +971,7 @@ FrontEnd::doSwitchOut() squash(0, 0); instBuffer.clear(); instBufferSize = 0; + feBuffer.clear(); status = Idle; }