rename_impl.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 1,362 行 · 第 1/3 页

HH
1,362
字号
            "history buffer %u (size=%i), until [sn:%lli].\n",            tid, tid, historyBuffer[tid].size(), inst_seq_num);    typename std::list<RenameHistory>::iterator hb_it =        historyBuffer[tid].end();    --hb_it;    if (historyBuffer[tid].empty()) {        DPRINTF(Rename, "[tid:%u]: History buffer is empty.\n", tid);        return;    } else if (hb_it->instSeqNum > inst_seq_num) {        DPRINTF(Rename, "[tid:%u]: Old sequence number encountered.  Ensure "                "that a syscall happened recently.\n", tid);        return;    }    // Commit all the renames up until (and including) the committed sequence    // number. Some or even all of the committed instructions may not have    // rename histories if they did not have destination registers that were    // renamed.    while (!historyBuffer[tid].empty() &&           hb_it != historyBuffer[tid].end() &&           (*hb_it).instSeqNum <= inst_seq_num) {        DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, "                "[sn:%lli].\n",                tid, (*hb_it).prevPhysReg, (*hb_it).instSeqNum);        freeList->addReg((*hb_it).prevPhysReg);        ++renameCommittedMaps;        historyBuffer[tid].erase(hb_it--);    }}template <class Impl>inline voidDefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst,unsigned tid){    assert(renameMap[tid] != 0);    unsigned num_src_regs = inst->numSrcRegs();    // Get the architectual register numbers from the source and    // destination operands, and redirect them to the right register.    // Will need to mark dependencies though.    for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {        RegIndex src_reg = inst->srcRegIdx(src_idx);        RegIndex flat_src_reg = src_reg;        if (src_reg < TheISA::FP_Base_DepTag) {            flat_src_reg = TheISA::flattenIntIndex(inst->tcBase(), src_reg);            DPRINTF(Rename, "Flattening index %d to %d.\n", (int)src_reg, (int)flat_src_reg);        } else if (src_reg < TheISA::Ctrl_Base_DepTag) {            src_reg = src_reg - TheISA::FP_Base_DepTag;            flat_src_reg = TheISA::flattenFloatIndex(inst->tcBase(), src_reg);            flat_src_reg += TheISA::NumIntRegs;        } else {            flat_src_reg = src_reg - TheISA::FP_Base_DepTag + TheISA::NumIntRegs;            DPRINTF(Rename, "Adjusting reg index from %d to %d.\n", src_reg, flat_src_reg);        }        inst->flattenSrcReg(src_idx, flat_src_reg);        // Look up the source registers to get the phys. register they've        // been renamed to, and set the sources to those registers.        PhysRegIndex renamed_reg = renameMap[tid]->lookup(flat_src_reg);        DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got "                "physical reg %i.\n", tid, (int)flat_src_reg,                (int)renamed_reg);        inst->renameSrcReg(src_idx, renamed_reg);        // See if the register is ready or not.        if (scoreboard->getReg(renamed_reg) == true) {            DPRINTF(Rename, "[tid:%u]: Register %d is ready.\n", tid, renamed_reg);            inst->markSrcRegReady(src_idx);        } else {            DPRINTF(Rename, "[tid:%u]: Register %d is not ready.\n", tid, renamed_reg);        }        ++renameRenameLookups;    }}template <class Impl>inline voidDefaultRename<Impl>::renameDestRegs(DynInstPtr &inst,unsigned tid){    typename RenameMap::RenameInfo rename_result;    unsigned num_dest_regs = inst->numDestRegs();    // Rename the destination registers.    for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {        RegIndex dest_reg = inst->destRegIdx(dest_idx);        RegIndex flat_dest_reg = dest_reg;        if (dest_reg < TheISA::FP_Base_DepTag) {            // Integer registers are flattened.            flat_dest_reg = TheISA::flattenIntIndex(inst->tcBase(), dest_reg);            DPRINTF(Rename, "Flattening index %d to %d.\n", (int)dest_reg, (int)flat_dest_reg);        } else {            // Floating point and Miscellaneous registers need their indexes            // adjusted to account for the expanded number of flattened int regs.            flat_dest_reg = dest_reg - TheISA::FP_Base_DepTag + TheISA::NumIntRegs;            DPRINTF(Rename, "Adjusting reg index from %d to %d.\n", dest_reg, flat_dest_reg);        }        inst->flattenDestReg(dest_idx, flat_dest_reg);        // Get the physical register that the destination will be        // renamed to.        rename_result = renameMap[tid]->rename(flat_dest_reg);        //Mark Scoreboard entry as not ready        scoreboard->unsetReg(rename_result.first);        DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "                "reg %i.\n", tid, (int)flat_dest_reg,                (int)rename_result.first);        // Record the rename information so that a history can be kept.        RenameHistory hb_entry(inst->seqNum, flat_dest_reg,                               rename_result.first,                               rename_result.second);        historyBuffer[tid].push_front(hb_entry);        DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer "                "(size=%i), [sn:%lli].\n",tid,                historyBuffer[tid].size(),                (*historyBuffer[tid].begin()).instSeqNum);        // Tell the instruction to rename the appropriate destination        // register (dest_idx) to the new physical register        // (rename_result.first), and record the previous physical        // register that the same logical register was renamed to        // (rename_result.second).        inst->renameDestReg(dest_idx,                            rename_result.first,                            rename_result.second);        ++renameRenamedOperands;    }}template <class Impl>inline intDefaultRename<Impl>::calcFreeROBEntries(unsigned tid){    int num_free = freeEntries[tid].robEntries -                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);    //DPRINTF(Rename,"[tid:%i]: %i rob free\n",tid,num_free);    return num_free;}template <class Impl>inline intDefaultRename<Impl>::calcFreeIQEntries(unsigned tid){    int num_free = freeEntries[tid].iqEntries -                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);    //DPRINTF(Rename,"[tid:%i]: %i iq free\n",tid,num_free);    return num_free;}template <class Impl>inline intDefaultRename<Impl>::calcFreeLSQEntries(unsigned tid){    int num_free = freeEntries[tid].lsqEntries -                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLSQ);    //DPRINTF(Rename,"[tid:%i]: %i lsq free\n",tid,num_free);    return num_free;}template <class Impl>unsignedDefaultRename<Impl>::validInsts(){    unsigned inst_count = 0;    for (int i=0; i<fromDecode->size; i++) {        if (!fromDecode->insts[i]->isSquashed())            inst_count++;    }    return inst_count;}template <class Impl>voidDefaultRename<Impl>::readStallSignals(unsigned tid){    if (fromIEW->iewBlock[tid]) {        stalls[tid].iew = true;    }    if (fromIEW->iewUnblock[tid]) {        assert(stalls[tid].iew);        stalls[tid].iew = false;    }    if (fromCommit->commitBlock[tid]) {        stalls[tid].commit = true;    }    if (fromCommit->commitUnblock[tid]) {        assert(stalls[tid].commit);        stalls[tid].commit = false;    }}template <class Impl>boolDefaultRename<Impl>::checkStall(unsigned tid){    bool ret_val = false;    if (stalls[tid].iew) {        DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid);        ret_val = true;    } else if (stalls[tid].commit) {        DPRINTF(Rename,"[tid:%i]: Stall from Commit stage detected.\n", tid);        ret_val = true;    } else if (calcFreeROBEntries(tid) <= 0) {        DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid);        ret_val = true;    } else if (calcFreeIQEntries(tid) <= 0) {        DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid);        ret_val = true;    } else if (calcFreeLSQEntries(tid) <= 0) {        DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid);        ret_val = true;    } else if (renameMap[tid]->numFreeEntries() <= 0) {        DPRINTF(Rename,"[tid:%i]: Stall: RenameMap has 0 free entries.\n", tid);        ret_val = true;    } else if (renameStatus[tid] == SerializeStall &&               (!emptyROB[tid] || instsInProgress[tid])) {        DPRINTF(Rename,"[tid:%i]: Stall: Serialize stall and ROB is not "                "empty.\n",                tid);        ret_val = true;    }    return ret_val;}template <class Impl>voidDefaultRename<Impl>::readFreeEntries(unsigned tid){    bool updated = false;    if (fromIEW->iewInfo[tid].usedIQ) {        freeEntries[tid].iqEntries =            fromIEW->iewInfo[tid].freeIQEntries;        updated = true;    }    if (fromIEW->iewInfo[tid].usedLSQ) {        freeEntries[tid].lsqEntries =            fromIEW->iewInfo[tid].freeLSQEntries;        updated = true;    }    if (fromCommit->commitInfo[tid].usedROB) {        freeEntries[tid].robEntries =            fromCommit->commitInfo[tid].freeROBEntries;        emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;        updated = true;    }    DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, Free LSQ: %i\n",            tid,            freeEntries[tid].iqEntries,            freeEntries[tid].robEntries,            freeEntries[tid].lsqEntries);    DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n",            tid, instsInProgress[tid]);}template <class Impl>boolDefaultRename<Impl>::checkSignalsAndUpdate(unsigned tid){    // Check if there's a squash signal, squash if there is    // Check stall signals, block if necessary.    // If status was blocked    //     check if stall conditions have passed    //         if so then go to unblocking    // If status was Squashing    //     check if squashing is not high.  Switch to running this cycle.    // If status was serialize stall    //     check if ROB is empty and no insts are in flight to the ROB    readFreeEntries(tid);    readStallSignals(tid);    if (fromCommit->commitInfo[tid].squash) {        DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from "                "commit.\n", tid);        squash(fromCommit->commitInfo[tid].doneSeqNum, tid);        return true;    }    if (fromCommit->commitInfo[tid].robSquashing) {        DPRINTF(Rename, "[tid:%u]: ROB is still squashing.\n", tid);        renameStatus[tid] = Squashing;        return true;    }    if (checkStall(tid)) {        return block(tid);    }    if (renameStatus[tid] == Blocked) {        DPRINTF(Rename, "[tid:%u]: Done blocking, switching to unblocking.\n",                tid);        renameStatus[tid] = Unblocking;        unblock(tid);        return true;    }    if (renameStatus[tid] == Squashing) {        // Switch status to running if rename isn't being told to block or        // squash this cycle.        if (resumeSerialize) {            DPRINTF(Rename, "[tid:%u]: Done squashing, switching to serialize.\n",                    tid);            renameStatus[tid] = SerializeStall;            return true;        } else if (resumeUnblocking) {            DPRINTF(Rename, "[tid:%u]: Done squashing, switching to unblocking.\n",                    tid);            renameStatus[tid] = Unblocking;            return true;        } else {            DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n",                    tid);            renameStatus[tid] = Running;            return false;        }    }    if (renameStatus[tid] == SerializeStall) {        // Stall ends once the ROB is free.        DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to "                "unblocking.\n", tid);        DynInstPtr serial_inst = serializeInst[tid];        renameStatus[tid] = Unblocking;        unblock(tid);        DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with "                "PC %#x.\n",                tid, serial_inst->seqNum, serial_inst->readPC());        // Put instruction into queue here.        serial_inst->clearSerializeBefore();        if (!skidBuffer[tid].empty()) {            skidBuffer[tid].push_front(serial_inst);        } else {            insts[tid].push_front(serial_inst);        }        DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename."                " Adding to front of list.\n", tid);        serializeInst[tid] = NULL;        return true;    }    // If we've reached this point, we have not gotten any signals that    // cause rename to change its status.  Rename remains the same as before.    return false;}template<class Impl>voidDefaultRename<Impl>::serializeAfter(InstQueue &inst_list,                                   unsigned tid){    if (inst_list.empty()) {        // Mark a bit to say that I must serialize on the next instruction.        serializeOnNextInst[tid] = true;        return;    }    // Set the next instruction as serializing.    inst_list.front()->setSerializeBefore();}template <class Impl>inline voidDefaultRename<Impl>::incrFullStat(const FullSource &source){    switch (source) {      case ROB:        ++renameROBFullEvents;        break;      case IQ:        ++renameIQFullEvents;        break;      case LSQ:        ++renameLSQFullEvents;        break;      default:        panic("Rename full stall stat should be incremented for a reason!");        break;    }}template <class Impl>voidDefaultRename<Impl>::dumpHistory(){    typename std::list<RenameHistory>::iterator buf_it;    for (int i = 0; i < numThreads; i++) {        buf_it = historyBuffer[i].begin();        while (buf_it != historyBuffer[i].end()) {            cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "                    "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,                    (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);            buf_it++;        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?