diff options
Diffstat (limited to 'src/cpu/o3/iew_impl.hh')
-rw-r--r-- | src/cpu/o3/iew_impl.hh | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index 8270a71b5..063394fdd 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -1186,9 +1186,16 @@ DefaultIEW<Impl>::executeInsts() fetchRedirect[tid] = false; } + // [mengjia] Validate/Expose any loads which are ready last cycle + // very tricky, need make the state consistent + // if we successfully commit sth, then we need to activate the stage or somehow + // problems happen when interacting with squash + // NOTE: we always send validations before execute load requests + ldstQueue.exposeLoads(); + // Uncomment this if you want to see all available instructions. // @todo This doesn't actually work anymore, we should fix it. -// printAvailableInsts(); + // printAvailableInsts(); // Execute/writeback any instructions that are available. int insts_to_execute = fromIssue->size; @@ -1235,18 +1242,40 @@ DefaultIEW<Impl>::executeInsts() DPRINTF(IEW, "Execute: Calculating address for memory " "reference.\n"); + DPRINTF(IEW, "Execute: %s\n", inst->staticInst->getName()); // Tell the LDSTQ to execute this instruction (if it is a load). if (inst->isLoad()) { // Loads will mark themselves as executed, and their writeback // event adds the instruction to the queue to commit + + // [InvisiSpec] a lifetime of a load + // always let it translate --> translation not complete, defer + // if !loadInExec, need to check whether there + // is a virtual fence ahead + // --> if existing virtual fence, defer + if (inst->fenceDelay()){ + DPRINTF(IEW, "Deferring load due to virtual fence.\n"); + inst->onlyWaitForFence(true); + instQueue.deferMemInst(inst); + continue; + } + fault = ldstQueue.executeLoad(inst); - if (inst->isTranslationDelayed() && + // [InvisiSpec] delay the load if there is a virtual fence ahead + if ((inst->isTranslationDelayed() ) && fault == NoFault) { // A hw page table walk is currently going on; the // instruction must be deferred. - DPRINTF(IEW, "Execute: Delayed translation, deferring " - "load.\n"); + DPRINTF(IEW, "Execute: Delayed translation, deferring load.\n"); + instQueue.deferMemInst(inst); + continue; + } + + if ((inst->specTLBMiss() ) && + fault == NoFault) { + DPRINTF(IEW, "Execute: Speculative load gets a TLB miss," + " deferring load.\n"); instQueue.deferMemInst(inst); continue; } @@ -1381,10 +1410,11 @@ DefaultIEW<Impl>::executeInsts() ++memOrderViolationEvents; } } - } + } // Update and record activity if we processed any instructions. if (inst_num) { + if (exeStatus == Idle) { exeStatus = Running; } @@ -1476,16 +1506,18 @@ DefaultIEW<Impl>::tick() dispatch(tid); } + ldstQueue.updateVisibleState(); + if (exeStatus != Squashing) { executeInsts(); - + writebackInsts(); // Have the instruction queue try to schedule any ready instructions. // (In actuality, this scheduling is for instructions that will // be executed next cycle.) instQueue.scheduleReadyInsts(); - + // Also should advance its own time buffers if the stage ran. // Not the best place for it, but this works (hopefully). issueToExecQueue.advance(); @@ -1502,6 +1534,7 @@ DefaultIEW<Impl>::tick() // Writeback any stores using any leftover bandwidth. ldstQueue.writebackStores(); + // Check the committed load/store signals to see if there's a load // or store to commit. Also check if it's being told to execute a |