From 8a21635effac179a81b618cab3df7d028999e84f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 05:48:59 -0500 Subject: Get rid of some typedefs which were hardly used, and move some stuff back here that shouldn't be in the architecture specific DynInst classes. --HG-- extra : convert_revision : dad0d7191acf773c16dc3ed9dd911f5e8bfc08b3 --- src/cpu/base_dyn_inst.hh | 111 +++++++++++++++++++++++++++++++++++--- src/cpu/o3/mips/dyn_inst.hh | 82 ++++------------------------ src/cpu/o3/mips/dyn_inst_impl.hh | 4 +- src/cpu/o3/sparc/dyn_inst.hh | 82 +++++----------------------- src/cpu/o3/sparc/dyn_inst_impl.hh | 4 +- 5 files changed, 131 insertions(+), 152 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 4a4555566..0f7976631 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -39,6 +39,7 @@ #include "base/fast_alloc.hh" #include "base/trace.hh" #include "config/full_system.hh" +#include "cpu/o3/comm.hh" #include "cpu/exetrace.hh" #include "cpu/inst_seq.hh" #include "cpu/op_class.hh" @@ -62,10 +63,6 @@ class BaseDynInst : public FastAlloc, public RefCounted typedef typename Impl::CPUType ImplCPU; typedef typename ImplCPU::ImplState ImplState; - // Binary machine instruction type. - typedef TheISA::MachInst MachInst; - // Extended machine instruction type - typedef TheISA::ExtMachInst ExtMachInst; // Logical register index type. typedef TheISA::RegIndex RegIndex; // Integer register type. @@ -236,7 +233,105 @@ class BaseDynInst : public FastAlloc, public RefCounted */ bool _readySrcRegIdx[MaxInstSrcRegs]; + protected: + /** Flattened register index of the destination registers of this + * instruction. + */ + TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs]; + + /** Flattened register index of the source registers of this + * instruction. + */ + TheISA::RegIndex _flatSrcRegIdx[TheISA::MaxInstSrcRegs]; + + /** Physical register index of the destination registers of this + * instruction. + */ + PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs]; + + /** Physical register index of the source registers of this + * instruction. + */ + PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs]; + + /** Physical register index of the previous producers of the + * architected destinations. + */ + PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs]; + public: + + /** Returns the physical register index of the i'th destination + * register. + */ + PhysRegIndex renamedDestRegIdx(int idx) const + { + return _destRegIdx[idx]; + } + + /** Returns the physical register index of the i'th source register. */ + PhysRegIndex renamedSrcRegIdx(int idx) const + { + return _srcRegIdx[idx]; + } + + /** Returns the flattened register index of the i'th destination + * register. + */ + TheISA::RegIndex flattenedDestRegIdx(int idx) const + { + return _flatDestRegIdx[idx]; + } + + /** Returns the flattened register index of the i'th source register */ + TheISA::RegIndex flattenedSrcRegIdx(int idx) const + { + return _flatSrcRegIdx[idx]; + } + + /** Returns the physical register index of the previous physical register + * that remapped to the same logical register index. + */ + PhysRegIndex prevDestRegIdx(int idx) const + { + return _prevDestRegIdx[idx]; + } + + /** Renames a destination register to a physical register. Also records + * the previous physical register that the logical register mapped to. + */ + void renameDestReg(int idx, + PhysRegIndex renamed_dest, + PhysRegIndex previous_rename) + { + _destRegIdx[idx] = renamed_dest; + _prevDestRegIdx[idx] = previous_rename; + } + + /** Renames a source logical register to the physical register which + * has/will produce that logical register's result. + * @todo: add in whether or not the source register is ready. + */ + void renameSrcReg(int idx, PhysRegIndex renamed_src) + { + _srcRegIdx[idx] = renamed_src; + } + + /** Flattens a source architectural register index into a logical index. + */ + void flattenSrcReg(int idx, TheISA::RegIndex flattened_src) + { + _flatSrcRegIdx[idx] = flattened_src; + } + + /** Flattens a destination architectural register index into a logical + * index. + */ + void flattenDestReg(int idx, TheISA::RegIndex flattened_dest) + { + _flatDestRegIdx[idx] = flattened_dest; + } + /** BaseDynInst constructor given a binary instruction. * @param inst The binary instruction. * @param PC The PC of the instruction. @@ -244,8 +339,8 @@ class BaseDynInst : public FastAlloc, public RefCounted * @param seq_num The sequence number of the instruction. * @param cpu Pointer to the instruction's CPU. */ - BaseDynInst(ExtMachInst inst, Addr PC, Addr pred_PC, InstSeqNum seq_num, - ImplCPU *cpu); + BaseDynInst(TheISA::ExtMachInst inst, Addr PC, Addr pred_PC, + InstSeqNum seq_num, ImplCPU *cpu); /** BaseDynInst constructor given a StaticInst pointer. * @param _staticInst The StaticInst for this BaseDynInst. @@ -298,9 +393,9 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Returns whether the instruction was predicted taken or not. */ bool predTaken() #if ISA_HAS_DELAY_SLOT - { return predPC != (nextPC + sizeof(MachInst)); } + { return predPC != (nextPC + sizeof(TheISA::MachInst)); } #else - { return predPC != (PC + sizeof(MachInst)); } + { return predPC != (PC + sizeof(TheISA::MachInst)); } #endif /** Returns whether the instruction mispredicted. */ diff --git a/src/cpu/o3/mips/dyn_inst.hh b/src/cpu/o3/mips/dyn_inst.hh index 9e95b2bfb..bf82168ce 100755 --- a/src/cpu/o3/mips/dyn_inst.hh +++ b/src/cpu/o3/mips/dyn_inst.hh @@ -54,10 +54,6 @@ class MipsDynInst : public BaseDynInst /** Typedef for the CPU. */ typedef typename Impl::O3CPU O3CPU; - /** Binary machine instruction type. */ - typedef TheISA::MachInst MachInst; - /** Extended machine instruction type. */ - typedef TheISA::ExtMachInst ExtMachInst; /** Logical register index type. */ typedef TheISA::RegIndex RegIndex; /** Integer register index type. */ @@ -127,22 +123,6 @@ class MipsDynInst : public BaseDynInst /** Calls a syscall. */ void syscall(int64_t callnum); - private: - /** Physical register index of the destination registers of this - * instruction. - */ - PhysRegIndex _destRegIdx[MaxInstDestRegs]; - - /** Physical register index of the source registers of this - * instruction. - */ - PhysRegIndex _srcRegIdx[MaxInstSrcRegs]; - - /** Physical register index of the previous producers of the - * architected destinations. - */ - PhysRegIndex _prevDestRegIdx[MaxInstDestRegs]; - public: // The register accessor methods provide the index of the @@ -158,27 +138,27 @@ class MipsDynInst : public BaseDynInst uint64_t readIntReg(const StaticInst *si, int idx) { - return this->cpu->readIntReg(_srcRegIdx[idx]); + return this->cpu->readIntReg(this->_srcRegIdx[idx]); } FloatReg readFloatReg(const StaticInst *si, int idx, int width) { - return this->cpu->readFloatReg(_srcRegIdx[idx], width); + return this->cpu->readFloatReg(this->_srcRegIdx[idx], width); } FloatReg readFloatReg(const StaticInst *si, int idx) { - return this->cpu->readFloatReg(_srcRegIdx[idx]); + return this->cpu->readFloatReg(this->_srcRegIdx[idx]); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) { - return this->cpu->readFloatRegBits(_srcRegIdx[idx], width); + return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx) { - return this->cpu->readFloatRegBits(_srcRegIdx[idx]); + return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]); } /** @todo: Make results into arrays so they can handle multiple dest @@ -186,77 +166,35 @@ class MipsDynInst : public BaseDynInst */ void setIntReg(const StaticInst *si, int idx, uint64_t val) { - this->cpu->setIntReg(_destRegIdx[idx], val); + this->cpu->setIntReg(this->_destRegIdx[idx], val); BaseDynInst::setIntReg(si, idx, val); } void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) { - this->cpu->setFloatReg(_destRegIdx[idx], val, width); + this->cpu->setFloatReg(this->_destRegIdx[idx], val, width); BaseDynInst::setFloatReg(si, idx, val, width); } void setFloatReg(const StaticInst *si, int idx, FloatReg val) { - this->cpu->setFloatReg(_destRegIdx[idx], val); + this->cpu->setFloatReg(this->_destRegIdx[idx], val); BaseDynInst::setFloatReg(si, idx, val); } void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val, int width) { - this->cpu->setFloatRegBits(_destRegIdx[idx], val, width); + this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width); BaseDynInst::setFloatRegBits(si, idx, val); } void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) { - this->cpu->setFloatRegBits(_destRegIdx[idx], val); + this->cpu->setFloatRegBits(this->_destRegIdx[idx], val); BaseDynInst::setFloatRegBits(si, idx, val); } - /** Returns the physical register index of the i'th destination - * register. - */ - PhysRegIndex renamedDestRegIdx(int idx) const - { - return _destRegIdx[idx]; - } - - /** Returns the physical register index of the i'th source register. */ - PhysRegIndex renamedSrcRegIdx(int idx) const - { - return _srcRegIdx[idx]; - } - - /** Returns the physical register index of the previous physical register - * that remapped to the same logical register index. - */ - PhysRegIndex prevDestRegIdx(int idx) const - { - return _prevDestRegIdx[idx]; - } - - /** Renames a destination register to a physical register. Also records - * the previous physical register that the logical register mapped to. - */ - void renameDestReg(int idx, - PhysRegIndex renamed_dest, - PhysRegIndex previous_rename) - { - _destRegIdx[idx] = renamed_dest; - _prevDestRegIdx[idx] = previous_rename; - } - - /** Renames a source logical register to the physical register which - * has/will produce that logical register's result. - * @todo: add in whether or not the source register is ready. - */ - void renameSrcReg(int idx, PhysRegIndex renamed_src) - { - _srcRegIdx[idx] = renamed_src; - } - public: /** Calculates EA part of a memory instruction. Currently unused, * though it may be useful in the future if we want to split diff --git a/src/cpu/o3/mips/dyn_inst_impl.hh b/src/cpu/o3/mips/dyn_inst_impl.hh index 5bc01b9b3..fa8cf6cb4 100755 --- a/src/cpu/o3/mips/dyn_inst_impl.hh +++ b/src/cpu/o3/mips/dyn_inst_impl.hh @@ -53,11 +53,11 @@ MipsDynInst::initVars() // as the normal register entries. It will allow the IQ to work // without any modifications. for (int i = 0; i < this->staticInst->numDestRegs(); i++) { - _destRegIdx[i] = this->staticInst->destRegIdx(i); + this->_destRegIdx[i] = this->staticInst->destRegIdx(i); } for (int i = 0; i < this->staticInst->numSrcRegs(); i++) { - _srcRegIdx[i] = this->staticInst->srcRegIdx(i); + this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i); this->_readySrcRegIdx[i] = 0; } } diff --git a/src/cpu/o3/sparc/dyn_inst.hh b/src/cpu/o3/sparc/dyn_inst.hh index f8d6bb63f..c645b832b 100644 --- a/src/cpu/o3/sparc/dyn_inst.hh +++ b/src/cpu/o3/sparc/dyn_inst.hh @@ -32,6 +32,7 @@ #define __CPU_O3_SPARC_DYN_INST_HH__ #include "arch/sparc/isa_traits.hh" +#include "arch/sparc/types.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/inst_seq.hh" #include "cpu/o3/sparc/cpu.hh" @@ -116,22 +117,6 @@ class SparcDynInst : public BaseDynInst void syscall(int64_t callnum); #endif - private: - /** Physical register index of the destination registers of this - * instruction. - */ - PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs]; - - /** Physical register index of the source registers of this - * instruction. - */ - PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs]; - - /** Physical register index of the previous producers of the - * architected destinations. - */ - PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs]; - public: // The register accessor methods provide the index of the @@ -147,28 +132,30 @@ class SparcDynInst : public BaseDynInst uint64_t readIntReg(const StaticInst *si, int idx) { - return this->cpu->readIntReg(_srcRegIdx[idx]); + uint64_t val = this->cpu->readIntReg(this->_srcRegIdx[idx]); + DPRINTF(Sparc, "Reading int reg %d (%d, %d) as %x\n", (int)this->_flatSrcRegIdx[idx], (int)this->_srcRegIdx[idx], idx, val); + return this->cpu->readIntReg(this->_srcRegIdx[idx]); } TheISA::FloatReg readFloatReg(const StaticInst *si, int idx, int width) { - return this->cpu->readFloatReg(_srcRegIdx[idx], width); + return this->cpu->readFloatReg(this->_flatSrcRegIdx[idx], width); } TheISA::FloatReg readFloatReg(const StaticInst *si, int idx) { - return this->cpu->readFloatReg(_srcRegIdx[idx]); + return this->cpu->readFloatReg(this->_flatSrcRegIdx[idx]); } TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) { - return this->cpu->readFloatRegBits(_srcRegIdx[idx], width); + return this->cpu->readFloatRegBits(this->_flatSrcRegIdx[idx], width); } TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx) { - return this->cpu->readFloatRegBits(_srcRegIdx[idx]); + return this->cpu->readFloatRegBits(this->_flatSrcRegIdx[idx]); } /** @todo: Make results into arrays so they can handle multiple dest @@ -176,79 +163,38 @@ class SparcDynInst : public BaseDynInst */ void setIntReg(const StaticInst *si, int idx, uint64_t val) { - this->cpu->setIntReg(_destRegIdx[idx], val); + DPRINTF(Sparc, "Setting int reg %d (%d, %d) to %x\n", (int)this->_flatDestRegIdx[idx], (int)this->_destRegIdx[idx], idx, val); + this->cpu->setIntReg(this->_destRegIdx[idx], val); BaseDynInst::setIntReg(si, idx, val); } void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val, int width) { - this->cpu->setFloatReg(_destRegIdx[idx], val, width); + this->cpu->setFloatReg(this->_flatDestRegIdx[idx], val, width); BaseDynInst::setFloatReg(si, idx, val, width); } void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val) { - this->cpu->setFloatReg(_destRegIdx[idx], val); + this->cpu->setFloatReg(this->_flatDestRegIdx[idx], val); BaseDynInst::setFloatReg(si, idx, val); } void setFloatRegBits(const StaticInst *si, int idx, TheISA::FloatRegBits val, int width) { - this->cpu->setFloatRegBits(_destRegIdx[idx], val, width); + this->cpu->setFloatRegBits(this->_flatDestRegIdx[idx], val, width); BaseDynInst::setFloatRegBits(si, idx, val); } void setFloatRegBits(const StaticInst *si, int idx, TheISA::FloatRegBits val) { - this->cpu->setFloatRegBits(_destRegIdx[idx], val); + this->cpu->setFloatRegBits(this->_flatDestRegIdx[idx], val); BaseDynInst::setFloatRegBits(si, idx, val); } - /** Returns the physical register index of the i'th destination - * register. - */ - PhysRegIndex renamedDestRegIdx(int idx) const - { - return _destRegIdx[idx]; - } - - /** Returns the physical register index of the i'th source register. */ - PhysRegIndex renamedSrcRegIdx(int idx) const - { - return _srcRegIdx[idx]; - } - - /** Returns the physical register index of the previous physical register - * that remapped to the same logical register index. - */ - PhysRegIndex prevDestRegIdx(int idx) const - { - return _prevDestRegIdx[idx]; - } - - /** Renames a destination register to a physical register. Also records - * the previous physical register that the logical register mapped to. - */ - void renameDestReg(int idx, - PhysRegIndex renamed_dest, - PhysRegIndex previous_rename) - { - _destRegIdx[idx] = renamed_dest; - _prevDestRegIdx[idx] = previous_rename; - } - - /** Renames a source logical register to the physical register which - * has/will produce that logical register's result. - * @todo: add in whether or not the source register is ready. - */ - void renameSrcReg(int idx, PhysRegIndex renamed_src) - { - _srcRegIdx[idx] = renamed_src; - } - public: /** Calculates EA part of a memory instruction. Currently unused, * though it may be useful in the future if we want to split diff --git a/src/cpu/o3/sparc/dyn_inst_impl.hh b/src/cpu/o3/sparc/dyn_inst_impl.hh index 210daace2..daf93d4a8 100644 --- a/src/cpu/o3/sparc/dyn_inst_impl.hh +++ b/src/cpu/o3/sparc/dyn_inst_impl.hh @@ -53,11 +53,11 @@ SparcDynInst::initVars() // as the normal register entries. It will allow the IQ to work // without any modifications. for (int i = 0; i < this->staticInst->numDestRegs(); i++) { - _destRegIdx[i] = this->staticInst->destRegIdx(i); + this->_destRegIdx[i] = this->staticInst->destRegIdx(i); } for (int i = 0; i < this->staticInst->numSrcRegs(); i++) { - _srcRegIdx[i] = this->staticInst->srcRegIdx(i); + this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i); this->_readySrcRegIdx[i] = 0; } } -- cgit v1.2.3 From 20340b5e26e05edd364eda5f69949cc8f957921b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 05:51:18 -0500 Subject: Change how optional delay slot instructions are detected and squashed. --HG-- extra : convert_revision : ffd019d4adc2fbbc0a663d8dc6ef73edce12511b --- src/cpu/o3/comm.hh | 2 +- src/cpu/o3/commit_impl.hh | 29 +++++++---------------------- src/cpu/o3/iew_impl.hh | 22 +++++++++++++++------- 3 files changed, 23 insertions(+), 30 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh index aa58fc20e..4683c77af 100644 --- a/src/cpu/o3/comm.hh +++ b/src/cpu/o3/comm.hh @@ -87,7 +87,7 @@ struct DefaultIEWDefaultCommit { bool squash[Impl::MaxThreads]; bool branchMispredict[Impl::MaxThreads]; bool branchTaken[Impl::MaxThreads]; - bool condDelaySlotBranch[Impl::MaxThreads]; + bool squashDelaySlot[Impl::MaxThreads]; uint64_t mispredPC[Impl::MaxThreads]; uint64_t nextPC[Impl::MaxThreads]; InstSeqNum squashedSeqNum[Impl::MaxThreads]; diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index e72679710..ba6a62b4d 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -728,27 +728,12 @@ DefaultCommit::commit() InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid]; #if ISA_HAS_DELAY_SLOT - InstSeqNum bdelay_done_seq_num; - bool squash_bdelay_slot; - - if (fromIEW->branchMispredict[tid]) { - if (fromIEW->branchTaken[tid] && - fromIEW->condDelaySlotBranch[tid]) { - DPRINTF(Commit, "[tid:%i]: Cond. delay slot branch" - "mispredicted as taken. Squashing after previous " - "inst, [sn:%i]\n", - tid, squashed_inst); - bdelay_done_seq_num = squashed_inst; - squash_bdelay_slot = true; - } else { - DPRINTF(Commit, "[tid:%i]: Branch Mispredict. Squashing " - "after delay slot [sn:%i]\n", tid, squashed_inst+1); - bdelay_done_seq_num = squashed_inst + 1; - squash_bdelay_slot = false; - } - } else { - bdelay_done_seq_num = squashed_inst; - } + InstSeqNum bdelay_done_seq_num = squashed_inst; + bool squash_bdelay_slot = fromIEW->squashDelaySlot[tid]; + + if (!squash_bdelay_slot) + bdelay_done_seq_num++; + #endif if (fromIEW->includeSquashInst[tid] == true) { @@ -1116,7 +1101,7 @@ DefaultCommit::commitHead(DynInstPtr &head_inst, unsigned inst_num) // Update the commit rename map for (int i = 0; i < head_inst->numDestRegs(); i++) { - renameMap[tid]->setEntry(head_inst->destRegIdx(i), + renameMap[tid]->setEntry(head_inst->flattenedDestRegIdx(i), head_inst->renamedDestRegIdx(i)); } diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index ba5260fe2..85db68576 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -481,18 +481,26 @@ DefaultIEW::squashDueToBranch(DynInstPtr &inst, unsigned tid) toCommit->branchMispredict[tid] = true; #if ISA_HAS_DELAY_SLOT - bool branch_taken = inst->readNextNPC() != - (inst->readNextPC() + sizeof(TheISA::MachInst)); + bool branch_taken = + (inst->readNextNPC() != (inst->readPC() + 2 * sizeof(TheISA::MachInst)) && + inst->readNextNPC() != (inst->readPC() + 3 * sizeof(TheISA::MachInst))); + DPRINTF(Sparc, "Branch taken = %s [sn:%i]\n", + branch_taken ? "true": "false", inst->seqNum); toCommit->branchTaken[tid] = branch_taken; - toCommit->condDelaySlotBranch[tid] = inst->isCondDelaySlot(); - - if (inst->isCondDelaySlot() && branch_taken) { + bool squashDelaySlot = + (inst->readNextPC() != inst->readPC() + sizeof(TheISA::MachInst)); + DPRINTF(Sparc, "Squash delay slot = %s [sn:%i]\n", + squashDelaySlot ? "true": "false", inst->seqNum); + toCommit->squashDelaySlot[tid] = squashDelaySlot; + //If we're squashing the delay slot, we need to pick back up at NextPC. + //Otherwise, NextPC isn't being squashed, so we should pick back up at + //NextNPC. + if (squashDelaySlot) toCommit->nextPC[tid] = inst->readNextPC(); - } else { + else toCommit->nextPC[tid] = inst->readNextNPC(); - } #else toCommit->branchTaken[tid] = inst->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst)); -- cgit v1.2.3 From 6456cb535cce8b35c36fa0366fc8766ecffbbf44 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 05:54:16 -0500 Subject: Added in endianness conversion on memory accesses as the data goes out. This will break the checker! --HG-- extra : convert_revision : b8191cab09ab8f3ced05693293f058382319ed8e --- src/cpu/o3/lsq_unit_impl.hh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 4facea9f9..379724166 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -596,7 +596,11 @@ LSQUnit::writebackStores() assert(!inst->memData); inst->memData = new uint8_t[64]; - memcpy(inst->memData, (uint8_t *)&storeQueue[storeWBIdx].data, + + TheISA::IntReg convertedData = + TheISA::htog(storeQueue[storeWBIdx].data); + + memcpy(inst->memData, (uint8_t *)&convertedData, req->getSize()); PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast); -- cgit v1.2.3 From 156cf0db51e48acf12d1d3ca36c9827fea0e6b7d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 05:55:23 -0500 Subject: Change rename to rename the flattened register index instead of the architectural one. --HG-- extra : convert_revision : 757866ad7a3c8be7382e1ffa71c60bc00c861f6f --- src/cpu/o3/rename_impl.hh | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 248d7deb6..84ccf6d5b 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -31,6 +31,8 @@ #include +#include "arch/isa_traits.hh" +#include "arch/regfile.hh" #include "config/full_system.hh" #include "cpu/o3/rename.hh" @@ -960,13 +962,19 @@ DefaultRename::renameSrcRegs(DynInstPtr &inst,unsigned tid) // 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); + } + 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(src_reg); + 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)src_reg, + "physical reg %i.\n", tid, (int)flat_src_reg, (int)renamed_reg); inst->renameSrcReg(src_idx, renamed_reg); @@ -993,20 +1001,27 @@ DefaultRename::renameDestRegs(DynInstPtr &inst,unsigned tid) // 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) { + flat_dest_reg = TheISA::flattenIntIndex(inst->tcBase(), dest_reg); + DPRINTF(Rename, "Flattening index %d to %d.\n", (int)dest_reg, (int)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(dest_reg); + 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)dest_reg, + "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, dest_reg, + RenameHistory hb_entry(inst->seqNum, flat_dest_reg, rename_result.first, rename_result.second); -- cgit v1.2.3 From 1d7d7df315e3bd9ddb3eedfed7f612e83778c252 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 05:56:34 -0500 Subject: Make syscalls flatten their register indices, and also call into the ISA's setSyscallReturn function rather than having a duplicated one. --HG-- extra : convert_revision : 1e83ef629a7fd143f2e35e68abaa56f81d6b9d9e --- src/cpu/o3/sparc/cpu_impl.hh | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/sparc/cpu_impl.hh b/src/cpu/o3/sparc/cpu_impl.hh index 536a620bf..f92d863cc 100644 --- a/src/cpu/o3/sparc/cpu_impl.hh +++ b/src/cpu/o3/sparc/cpu_impl.hh @@ -285,35 +285,24 @@ template TheISA::IntReg SparcO3CPU::getSyscallArg(int i, int tid) { - return this->readArchIntReg(SparcISA::ArgumentReg0 + i, tid); + IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid), + SparcISA::ArgumentReg0 + i); + return this->readArchIntReg(idx, tid); } template void SparcO3CPU::setSyscallArg(int i, IntReg val, int tid) { - this->setArchIntReg(SparcISA::ArgumentReg0 + i, val, tid); + IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid), + SparcISA::ArgumentReg0 + i); + this->setArchIntReg(idx, val, tid); } template void SparcO3CPU::setSyscallReturn(SyscallReturn return_value, int tid) { - // check for error condition. SPARC syscall convention is to - // indicate success/failure in reg the carry bit of the ccr - // and put the return value itself in the standard return value reg (). - if (return_value.successful()) { - // no error, clear XCC.C - this->setMiscReg(SparcISA::MISCREG_CCR, - this->readMiscReg(SparcISA::MISCREG_CCR, tid) & 0xEE, tid); - this->setArchIntReg(SparcISA::ReturnValueReg, - return_value.value(), tid); - } else { - // got an error, set XCC.C - this->setMiscReg(SparcISA::MISCREG_CCR, - this->readMiscReg(SparcISA::MISCREG_CCR, tid) | 0x11, tid); - this->setArchIntReg(SparcISA::ReturnValueReg, - return_value.value(), tid); - } + TheISA::setSyscallReturn(return_value, this->tcBase(tid)); } #endif -- cgit v1.2.3 From 1886795368e0f07875f8f7ff70f09a8e200e6a85 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 05:58:07 -0500 Subject: Don't panic, but this needs to be fixed. --HG-- extra : convert_revision : 7a4aed238d437dbb2cc5946b3045d53697070a27 --- src/cpu/o3/sparc/thread_context.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/sparc/thread_context.hh b/src/cpu/o3/sparc/thread_context.hh index 69d1e2d04..3955de0cc 100644 --- a/src/cpu/o3/sparc/thread_context.hh +++ b/src/cpu/o3/sparc/thread_context.hh @@ -62,7 +62,7 @@ class SparcTC : public O3ThreadContext virtual void changeRegFileContext(TheISA::RegContextParam param, TheISA::RegContextVal val) { - panic("This doesn't make sense!\n"); + //XXX Ignore this for now. This -really- needs to get fixed. } -- cgit v1.2.3 From 75b93179ab96de17c1ea62c3928d5fca9d5eb1be Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 06:00:04 -0500 Subject: Flattening and syscallReturn fixes src/cpu/o3/thread_context_impl.hh: Use flattened indices src/cpu/simple_thread.hh: Use flattened indices, and pass a thread context to setSyscallReturn rather than a register file. src/cpu/thread_context.hh: The SyscallReturn class is no longer in arch/syscallreturn.hh --HG-- extra : convert_revision : ed84bb8ac5ef0774526ecd0d7270b0c60cd3708e --- src/cpu/o3/thread_context_impl.hh | 3 +++ src/cpu/simple_thread.hh | 14 +++++++++----- src/cpu/thread_context.hh | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index 0180756e3..29c00a0c3 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -29,6 +29,7 @@ * Korey Sewell */ +#include "arch/regfile.hh" #include "cpu/o3/thread_context.hh" #include "cpu/quiesce_event.hh" @@ -303,6 +304,7 @@ template uint64_t O3ThreadContext::readIntReg(int reg_idx) { + reg_idx = TheISA::flattenIntIndex(this, reg_idx); return cpu->readArchIntReg(reg_idx, thread->readTid()); } @@ -347,6 +349,7 @@ template void O3ThreadContext::setIntReg(int reg_idx, uint64_t val) { + reg_idx = TheISA::flattenIntIndex(this, reg_idx); cpu->setArchIntReg(reg_idx, val, thread->readTid()); // Squash if we're not already in a state update mode. diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index e8757c8c2..acbefeb67 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -33,6 +33,8 @@ #define __CPU_SIMPLE_THREAD_HH__ #include "arch/isa_traits.hh" +#include "arch/regfile.hh" +#include "arch/syscallreturn.hh" #include "config/full_system.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" @@ -319,7 +321,7 @@ class SimpleThread : public ThreadState // uint64_t readIntReg(int reg_idx) { - return regs.readIntReg(reg_idx); + return regs.readIntReg(TheISA::flattenIntIndex(getTC(), reg_idx)); } FloatReg readFloatReg(int reg_idx, int width) @@ -344,7 +346,7 @@ class SimpleThread : public ThreadState void setIntReg(int reg_idx, uint64_t val) { - regs.setIntReg(reg_idx, val); + regs.setIntReg(TheISA::flattenIntIndex(getTC(), reg_idx), val); } void setFloatReg(int reg_idx, FloatReg val, int width) @@ -445,18 +447,20 @@ class SimpleThread : public ThreadState #if !FULL_SYSTEM TheISA::IntReg getSyscallArg(int i) { - return regs.readIntReg(TheISA::ArgumentReg0 + i); + return regs.readIntReg(TheISA::flattenIntIndex(getTC(), + TheISA::ArgumentReg0 + i)); } // used to shift args for indirect syscall void setSyscallArg(int i, TheISA::IntReg val) { - regs.setIntReg(TheISA::ArgumentReg0 + i, val); + regs.setIntReg(TheISA::flattenIntIndex(getTC(), + TheISA::ArgumentReg0 + i), val); } void setSyscallReturn(SyscallReturn return_value) { - TheISA::setSyscallReturn(return_value, ®s); + TheISA::setSyscallReturn(return_value, getTC()); } void syscall(int64_t callnum) diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index baeb7a8be..2540df46b 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -32,13 +32,13 @@ #define __CPU_THREAD_CONTEXT_HH__ #include "arch/regfile.hh" -#include "arch/syscallreturn.hh" #include "arch/types.hh" #include "config/full_system.hh" #include "mem/request.hh" #include "sim/faults.hh" #include "sim/host.hh" #include "sim/serialize.hh" +#include "sim/syscallreturn.hh" #include "sim/byteswap.hh" // @todo: Figure out a more architecture independent way to obtain the ITB and -- cgit v1.2.3 From be29adf51cb115e7e55321bd58b7f6593e6d0080 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 06:02:13 -0500 Subject: Added a DPRINTF to print out the actual value pulled from memory. --HG-- extra : convert_revision : 18780f753a7e98f8de3047dd6781b944b0826b4e --- src/cpu/o3/fetch_impl.hh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/cpu') diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 63d22b293..8213e8fa2 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1155,6 +1155,8 @@ DefaultFetch::fetch(bool &status_change) "[sn:%lli]\n", tid, instruction->readPC(), inst_seq); + DPRINTF(Fetch, "[tid:%i]: MachInst is %#x\n", tid, ext_inst); + DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", tid, instruction->staticInst->disassemble(fetch_PC)); -- cgit v1.2.3 From 6826ee53dbab2e1a762aebb478a1c41389a4d07c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 11:36:40 -0500 Subject: Got rid of some typedefs, moved the tlbs to the base o3 cpu, and called the architecture defined setSyscallReturn function instead of a duplicate copy. src/cpu/o3/alpha/cpu.hh: Got rid of some typedefs, and moved the tlbs to the base o3 cpu. src/cpu/o3/alpha/thread_context.hh: src/cpu/o3/cpu.cc: Moved the tlbs to the base o3 cpu. --HG-- extra : convert_revision : 1805613aa230b8974a226ee3d2584c85f7a578aa --- src/cpu/o3/alpha/cpu.hh | 41 ++++++++++---------------------------- src/cpu/o3/alpha/cpu_impl.hh | 29 +++++++-------------------- src/cpu/o3/alpha/thread_context.hh | 6 ------ src/cpu/o3/cpu.cc | 4 ++++ src/cpu/o3/cpu.hh | 24 ++++++++++++---------- 5 files changed, 35 insertions(+), 69 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/alpha/cpu.hh b/src/cpu/o3/alpha/cpu.hh index 0078db69f..4a2086296 100644 --- a/src/cpu/o3/alpha/cpu.hh +++ b/src/cpu/o3/alpha/cpu.hh @@ -37,12 +37,6 @@ #include "cpu/o3/cpu.hh" #include "sim/byteswap.hh" -namespace TheISA -{ - class ITB; - class DTB; -} - class EndQuiesceEvent; namespace Kernel { class Statistics; @@ -61,14 +55,6 @@ class TranslatingPort; template class AlphaO3CPU : public FullO3CPU { - protected: - typedef TheISA::IntReg IntReg; - typedef TheISA::FloatReg FloatReg; - typedef TheISA::FloatRegBits FloatRegBits; - typedef TheISA::MiscReg MiscReg; - typedef TheISA::RegFile RegFile; - typedef TheISA::MiscRegFile MiscRegFile; - public: typedef O3ThreadState ImplState; typedef O3ThreadState Thread; @@ -77,13 +63,6 @@ class AlphaO3CPU : public FullO3CPU /** Constructs an AlphaO3CPU with the given parameters. */ AlphaO3CPU(Params *params); -#if FULL_SYSTEM - /** ITB pointer. */ - AlphaISA::ITB *itb; - /** DTB pointer. */ - AlphaISA::DTB *dtb; -#endif - /** Registers statistics. */ void regStats(); @@ -91,19 +70,19 @@ class AlphaO3CPU : public FullO3CPU /** Translates instruction requestion. */ Fault translateInstReq(RequestPtr &req, Thread *thread) { - return itb->translate(req, thread->getTC()); + return this->itb->translate(req, thread->getTC()); } /** Translates data read request. */ Fault translateDataReadReq(RequestPtr &req, Thread *thread) { - return dtb->translate(req, thread->getTC(), false); + return this->dtb->translate(req, thread->getTC(), false); } /** Translates data write request. */ Fault translateDataWriteReq(RequestPtr &req, Thread *thread) { - return dtb->translate(req, thread->getTC(), true); + return this->dtb->translate(req, thread->getTC(), true); } #else @@ -127,20 +106,22 @@ class AlphaO3CPU : public FullO3CPU #endif /** Reads a miscellaneous register. */ - MiscReg readMiscReg(int misc_reg, unsigned tid); + TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid); /** Reads a misc. register, including any side effects the read * might have as defined by the architecture. */ - MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid); + TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid); /** Sets a miscellaneous register. */ - void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid); + void setMiscReg(int misc_reg, const TheISA::MiscReg &val, + unsigned tid); /** Sets a misc. register, including any side effects the write * might have as defined by the architecture. */ - void setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid); + void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val, + unsigned tid); /** Initiates a squash of all in-flight instructions for a given * thread. The source of the squash is an external update of @@ -175,10 +156,10 @@ class AlphaO3CPU : public FullO3CPU */ void syscall(int64_t callnum, int tid); /** Gets a syscall argument. */ - IntReg getSyscallArg(int i, int tid); + TheISA::IntReg getSyscallArg(int i, int tid); /** Used to shift args for indirect syscall. */ - void setSyscallArg(int i, IntReg val, int tid); + void setSyscallArg(int i, TheISA::IntReg val, int tid); /** Sets the return value of a syscall. */ void setSyscallReturn(SyscallReturn return_value, int tid); diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index 98fd0699a..fb0962056 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -55,12 +55,7 @@ #endif template -AlphaO3CPU::AlphaO3CPU(Params *params) -#if FULL_SYSTEM - : FullO3CPU(params), itb(params->itb), dtb(params->dtb) -#else - : FullO3CPU(params) -#endif +AlphaO3CPU::AlphaO3CPU(Params *params) : FullO3CPU(params) { DPRINTF(O3CPU, "Creating AlphaO3CPU object.\n"); @@ -173,15 +168,16 @@ AlphaO3CPU::readMiscRegWithEffect(int misc_reg, unsigned tid) template void -AlphaO3CPU::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid) +AlphaO3CPU::setMiscReg(int misc_reg, const TheISA::MiscReg &val, + unsigned tid) { this->regFile.setMiscReg(misc_reg, val, tid); } template void -AlphaO3CPU::setMiscRegWithEffect(int misc_reg, const MiscReg &val, - unsigned tid) +AlphaO3CPU::setMiscRegWithEffect(int misc_reg, + const TheISA::MiscReg &val, unsigned tid) { this->regFile.setMiscRegWithEffect(misc_reg, val, tid); } @@ -315,7 +311,7 @@ AlphaO3CPU::getSyscallArg(int i, int tid) template void -AlphaO3CPU::setSyscallArg(int i, IntReg val, int tid) +AlphaO3CPU::setSyscallArg(int i, TheISA::IntReg val, int tid) { this->setArchIntReg(AlphaISA::ArgumentReg0 + i, val, tid); } @@ -324,17 +320,6 @@ template void AlphaO3CPU::setSyscallReturn(SyscallReturn return_value, int tid) { - // check for error condition. Alpha syscall convention is to - // indicate success/failure in reg a3 (r19) and put the - // return value itself in the standard return value reg (v0). - if (return_value.successful()) { - // no error - this->setArchIntReg(TheISA::SyscallSuccessReg, 0, tid); - this->setArchIntReg(TheISA::ReturnValueReg, return_value.value(), tid); - } else { - // got an error, return details - this->setArchIntReg(TheISA::SyscallSuccessReg, (IntReg) -1, tid); - this->setArchIntReg(TheISA::ReturnValueReg, -return_value.value(), tid); - } + TheISA::setSyscallReturn(return_value, this->tcBase(tid)); } #endif diff --git a/src/cpu/o3/alpha/thread_context.hh b/src/cpu/o3/alpha/thread_context.hh index bcecb7087..e4a6735c2 100644 --- a/src/cpu/o3/alpha/thread_context.hh +++ b/src/cpu/o3/alpha/thread_context.hh @@ -36,12 +36,6 @@ class AlphaTC : public O3ThreadContext { public: #if FULL_SYSTEM - /** Returns a pointer to the ITB. */ - virtual AlphaISA::ITB *getITBPtr() { return this->cpu->itb; } - - /** Returns a pointer to the DTB. */ - virtual AlphaISA::DTB *getDTBPtr() { return this->cpu->dtb; } - /** Returns pointer to the quiesce event. */ virtual EndQuiesceEvent *getQuiesceEvent() { diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index a5a00015f..4056d876f 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -149,6 +149,10 @@ FullO3CPU::DeallocateContextEvent::description() template FullO3CPU::FullO3CPU(Params *params) : BaseO3CPU(params), +#if FULL_SYSTEM + itb(params->itb), + dtb(params->dtb), +#endif tickEvent(this), removeInstsThisCycle(false), fetch(params), diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 2bf9cb23b..d217a3e85 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -91,9 +91,6 @@ template class FullO3CPU : public BaseO3CPU { public: - typedef TheISA::FloatReg FloatReg; - typedef TheISA::FloatRegBits FloatRegBits; - // Typedefs from the Impl here. typedef typename Impl::CPUPol CPUPolicy; typedef typename Impl::Params Params; @@ -114,6 +111,11 @@ class FullO3CPU : public BaseO3CPU SwitchedOut }; +#if FULL_SYSTEM + TheISA::ITB * itb; + TheISA::DTB * dtb; +#endif + /** Overall CPU status. */ Status _status; @@ -382,23 +384,23 @@ class FullO3CPU : public BaseO3CPU /** Register accessors. Index refers to the physical register index. */ uint64_t readIntReg(int reg_idx); - FloatReg readFloatReg(int reg_idx); + TheISA::FloatReg readFloatReg(int reg_idx); - FloatReg readFloatReg(int reg_idx, int width); + TheISA::FloatReg readFloatReg(int reg_idx, int width); - FloatRegBits readFloatRegBits(int reg_idx); + TheISA::FloatRegBits readFloatRegBits(int reg_idx); - FloatRegBits readFloatRegBits(int reg_idx, int width); + TheISA::FloatRegBits readFloatRegBits(int reg_idx, int width); void setIntReg(int reg_idx, uint64_t val); - void setFloatReg(int reg_idx, FloatReg val); + void setFloatReg(int reg_idx, TheISA::FloatReg val); - void setFloatReg(int reg_idx, FloatReg val, int width); + void setFloatReg(int reg_idx, TheISA::FloatReg val, int width); - void setFloatRegBits(int reg_idx, FloatRegBits val); + void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val); - void setFloatRegBits(int reg_idx, FloatRegBits val, int width); + void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val, int width); uint64_t readArchIntReg(int reg_idx, unsigned tid); -- cgit v1.2.3 From ef942ceecba7ca1affee5545ba9004d32d1e8536 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 11:37:39 -0500 Subject: Moved the RegIdx arrays to the base dyninst. --HG-- extra : convert_revision : d705cde25c2cf1add20669e99d086add49141518 --- src/cpu/o3/alpha/dyn_inst.hh | 78 +++++---------------------------------- src/cpu/o3/alpha/dyn_inst_impl.hh | 4 +- 2 files changed, 12 insertions(+), 70 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh index 31df8ff78..4e2ce63df 100644 --- a/src/cpu/o3/alpha/dyn_inst.hh +++ b/src/cpu/o3/alpha/dyn_inst.hh @@ -134,22 +134,6 @@ class AlphaDynInst : public BaseDynInst void syscall(int64_t callnum); #endif - private: - /** Physical register index of the destination registers of this - * instruction. - */ - PhysRegIndex _destRegIdx[MaxInstDestRegs]; - - /** Physical register index of the source registers of this - * instruction. - */ - PhysRegIndex _srcRegIdx[MaxInstSrcRegs]; - - /** Physical register index of the previous producers of the - * architected destinations. - */ - PhysRegIndex _prevDestRegIdx[MaxInstDestRegs]; - public: // The register accessor methods provide the index of the @@ -165,27 +149,27 @@ class AlphaDynInst : public BaseDynInst uint64_t readIntReg(const StaticInst *si, int idx) { - return this->cpu->readIntReg(_srcRegIdx[idx]); + return this->cpu->readIntReg(this->_srcRegIdx[idx]); } FloatReg readFloatReg(const StaticInst *si, int idx, int width) { - return this->cpu->readFloatReg(_srcRegIdx[idx], width); + return this->cpu->readFloatReg(this->_srcRegIdx[idx], width); } FloatReg readFloatReg(const StaticInst *si, int idx) { - return this->cpu->readFloatReg(_srcRegIdx[idx]); + return this->cpu->readFloatReg(this->_srcRegIdx[idx]); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) { - return this->cpu->readFloatRegBits(_srcRegIdx[idx], width); + return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx) { - return this->cpu->readFloatRegBits(_srcRegIdx[idx]); + return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]); } /** @todo: Make results into arrays so they can handle multiple dest @@ -193,77 +177,35 @@ class AlphaDynInst : public BaseDynInst */ void setIntReg(const StaticInst *si, int idx, uint64_t val) { - this->cpu->setIntReg(_destRegIdx[idx], val); + this->cpu->setIntReg(this->_destRegIdx[idx], val); BaseDynInst::setIntReg(si, idx, val); } void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) { - this->cpu->setFloatReg(_destRegIdx[idx], val, width); + this->cpu->setFloatReg(this->_destRegIdx[idx], val, width); BaseDynInst::setFloatReg(si, idx, val, width); } void setFloatReg(const StaticInst *si, int idx, FloatReg val) { - this->cpu->setFloatReg(_destRegIdx[idx], val); + this->cpu->setFloatReg(this->_destRegIdx[idx], val); BaseDynInst::setFloatReg(si, idx, val); } void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val, int width) { - this->cpu->setFloatRegBits(_destRegIdx[idx], val, width); + this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width); BaseDynInst::setFloatRegBits(si, idx, val); } void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) { - this->cpu->setFloatRegBits(_destRegIdx[idx], val); + this->cpu->setFloatRegBits(this->_destRegIdx[idx], val); BaseDynInst::setFloatRegBits(si, idx, val); } - /** Returns the physical register index of the i'th destination - * register. - */ - PhysRegIndex renamedDestRegIdx(int idx) const - { - return _destRegIdx[idx]; - } - - /** Returns the physical register index of the i'th source register. */ - PhysRegIndex renamedSrcRegIdx(int idx) const - { - return _srcRegIdx[idx]; - } - - /** Returns the physical register index of the previous physical register - * that remapped to the same logical register index. - */ - PhysRegIndex prevDestRegIdx(int idx) const - { - return _prevDestRegIdx[idx]; - } - - /** Renames a destination register to a physical register. Also records - * the previous physical register that the logical register mapped to. - */ - void renameDestReg(int idx, - PhysRegIndex renamed_dest, - PhysRegIndex previous_rename) - { - _destRegIdx[idx] = renamed_dest; - _prevDestRegIdx[idx] = previous_rename; - } - - /** Renames a source logical register to the physical register which - * has/will produce that logical register's result. - * @todo: add in whether or not the source register is ready. - */ - void renameSrcReg(int idx, PhysRegIndex renamed_src) - { - _srcRegIdx[idx] = renamed_src; - } - public: /** Calculates EA part of a memory instruction. Currently unused, * though it may be useful in the future if we want to split diff --git a/src/cpu/o3/alpha/dyn_inst_impl.hh b/src/cpu/o3/alpha/dyn_inst_impl.hh index 6fc548a85..02432f721 100644 --- a/src/cpu/o3/alpha/dyn_inst_impl.hh +++ b/src/cpu/o3/alpha/dyn_inst_impl.hh @@ -53,11 +53,11 @@ AlphaDynInst::initVars() // as the normal register entries. It will allow the IQ to work // without any modifications. for (int i = 0; i < this->staticInst->numDestRegs(); i++) { - _destRegIdx[i] = this->staticInst->destRegIdx(i); + this->_destRegIdx[i] = this->staticInst->destRegIdx(i); } for (int i = 0; i < this->staticInst->numSrcRegs(); i++) { - _srcRegIdx[i] = this->staticInst->srcRegIdx(i); + this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i); this->_readySrcRegIdx[i] = 0; } } -- cgit v1.2.3 From 07a4e2cd36c35ab7b6be356d9bcf3b58b5ef6794 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 11:38:39 -0500 Subject: Use the setSyscallReturn defined in arch rather than duplicating it here. --HG-- extra : convert_revision : 862ece59aa253b52b6744a0a76738d5ee19561b3 --- src/cpu/o3/mips/cpu_impl.hh | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/mips/cpu_impl.hh b/src/cpu/o3/mips/cpu_impl.hh index 08e9ba483..e7dbd3aba 100644 --- a/src/cpu/o3/mips/cpu_impl.hh +++ b/src/cpu/o3/mips/cpu_impl.hh @@ -220,16 +220,6 @@ template void MipsO3CPU::setSyscallReturn(SyscallReturn return_value, int tid) { - // check for error condition. - if (return_value.successful()) { - // no error - this->setArchIntReg(TheISA::SyscallSuccessReg, 0, tid); - this->setArchIntReg(TheISA::ReturnValueReg, return_value.value(), tid); - } else { - // got an error, return details - this->setArchIntReg(TheISA::SyscallSuccessReg, - (TheISA::IntReg) -1, tid); - this->setArchIntReg(TheISA::ReturnValueReg, -return_value.value(), tid); - } + TheISA::setSyscallReturn(return_value, this->tcBase(tid)); } #endif -- cgit v1.2.3 From f04fcf58f1dc7adcf67e19ca00ff741775982dfa Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 11:39:49 -0500 Subject: Got rid of some typedefs and moved the tlbs into the base o3 cpu. --HG-- extra : convert_revision : dcd1d2a64fd91aded15c8c763a78b4eebf421870 --- src/cpu/o3/sparc/cpu.hh | 60 +++++++------------------------------- src/cpu/o3/sparc/cpu_impl.hh | 20 +++++-------- src/cpu/o3/sparc/thread_context.hh | 6 ---- src/cpu/o3/thread_context.hh | 8 +++++ 4 files changed, 27 insertions(+), 67 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/sparc/cpu.hh b/src/cpu/o3/sparc/cpu.hh index c4df79832..73c859367 100644 --- a/src/cpu/o3/sparc/cpu.hh +++ b/src/cpu/o3/sparc/cpu.hh @@ -37,12 +37,6 @@ #include "cpu/o3/cpu.hh" #include "sim/byteswap.hh" -namespace TheISA -{ - class ITB; - class DTB; -} - class EndQuiesceEvent; namespace Kernel { class Statistics; @@ -61,14 +55,6 @@ class TranslatingPort; template class SparcO3CPU : public FullO3CPU { - protected: - typedef TheISA::IntReg IntReg; - typedef TheISA::FloatReg FloatReg; - typedef TheISA::FloatRegBits FloatRegBits; - typedef TheISA::MiscReg MiscReg; - typedef TheISA::RegFile RegFile; - typedef TheISA::MiscRegFile MiscRegFile; - public: typedef O3ThreadState ImplState; typedef O3ThreadState Thread; @@ -77,13 +63,6 @@ class SparcO3CPU : public FullO3CPU /** Constructs an AlphaO3CPU with the given parameters. */ SparcO3CPU(Params *params); -#if FULL_SYSTEM - /** ITB pointer. */ - SparcISA::ITB *itb; - /** DTB pointer. */ - SparcISA::DTB *dtb; -#endif - /** Registers statistics. */ void regStats(); @@ -91,19 +70,19 @@ class SparcO3CPU : public FullO3CPU /** Translates instruction requestion. */ Fault translateInstReq(RequestPtr &req, Thread *thread) { - return itb->translate(req, thread->getTC()); + return this->itb->translate(req, thread->getTC()); } /** Translates data read request. */ Fault translateDataReadReq(RequestPtr &req, Thread *thread) { - return dtb->translate(req, thread->getTC(), false); + return this->dtb->translate(req, thread->getTC(), false); } /** Translates data write request. */ Fault translateDataWriteReq(RequestPtr &req, Thread *thread) { - return dtb->translate(req, thread->getTC(), true); + return this->dtb->translate(req, thread->getTC(), true); } #else @@ -127,20 +106,21 @@ class SparcO3CPU : public FullO3CPU #endif /** Reads a miscellaneous register. */ - MiscReg readMiscReg(int misc_reg, unsigned tid); + TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid); /** Reads a misc. register, including any side effects the read * might have as defined by the architecture. */ - MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid); + TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid); /** Sets a miscellaneous register. */ - void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid); + void setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid); /** Sets a misc. register, including any side effects the write * might have as defined by the architecture. */ - void setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid); + void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val, + unsigned tid); /** Initiates a squash of all in-flight instructions for a given * thread. The source of the squash is an external update of @@ -148,24 +128,6 @@ class SparcO3CPU : public FullO3CPU */ void squashFromTC(unsigned tid); -#if FULL_SYSTEM - /** Posts an interrupt. */ - void post_interrupt(int int_num, int index); - /** HW return from error interrupt. */ - Fault hwrei(unsigned tid); - - bool simPalCheck(int palFunc, unsigned tid); - - /** Returns the Fault for any valid interrupt. */ - Fault getInterrupts(); - - /** Processes any an interrupt fault. */ - void processInterrupts(Fault interrupt); - - /** Halts the CPU. */ - void halt() { panic("Halt not implemented!\n"); } -#endif - /** Traps to handle given fault. */ void trap(Fault fault, unsigned tid); @@ -175,10 +137,10 @@ class SparcO3CPU : public FullO3CPU */ void syscall(int64_t callnum, int tid); /** Gets a syscall argument. */ - IntReg getSyscallArg(int i, int tid); + TheISA::IntReg getSyscallArg(int i, int tid); /** Used to shift args for indirect syscall. */ - void setSyscallArg(int i, IntReg val, int tid); + void setSyscallArg(int i, TheISA::IntReg val, int tid); /** Sets the return value of a syscall. */ void setSyscallReturn(SyscallReturn return_value, int tid); @@ -204,4 +166,4 @@ class SparcO3CPU : public FullO3CPU bool lockFlag; }; -#endif // __CPU_O3_ALPHA_CPU_HH__ +#endif // __CPU_O3_SPARC_CPU_HH__ diff --git a/src/cpu/o3/sparc/cpu_impl.hh b/src/cpu/o3/sparc/cpu_impl.hh index f92d863cc..4a194cbda 100644 --- a/src/cpu/o3/sparc/cpu_impl.hh +++ b/src/cpu/o3/sparc/cpu_impl.hh @@ -55,12 +55,7 @@ #endif template -SparcO3CPU::SparcO3CPU(Params *params) -#if FULL_SYSTEM - : FullO3CPU(params), itb(params->itb), dtb(params->dtb) -#else - : FullO3CPU(params) -#endif +SparcO3CPU::SparcO3CPU(Params *params) : FullO3CPU(params) { DPRINTF(O3CPU, "Creating SparcO3CPU object.\n"); @@ -172,15 +167,16 @@ SparcO3CPU::readMiscRegWithEffect(int misc_reg, unsigned tid) template void -SparcO3CPU::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid) +SparcO3CPU::setMiscReg(int misc_reg, + const SparcISA::MiscReg &val, unsigned tid) { this->regFile.setMiscReg(misc_reg, val, tid); } template void -SparcO3CPU::setMiscRegWithEffect(int misc_reg, const MiscReg &val, - unsigned tid) +SparcO3CPU::setMiscRegWithEffect(int misc_reg, + const SparcISA::MiscReg &val, unsigned tid) { this->regFile.setMiscRegWithEffect(misc_reg, val, tid); } @@ -285,16 +281,16 @@ template TheISA::IntReg SparcO3CPU::getSyscallArg(int i, int tid) { - IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid), + TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid), SparcISA::ArgumentReg0 + i); return this->readArchIntReg(idx, tid); } template void -SparcO3CPU::setSyscallArg(int i, IntReg val, int tid) +SparcO3CPU::setSyscallArg(int i, TheISA::IntReg val, int tid) { - IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid), + TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid), SparcISA::ArgumentReg0 + i); this->setArchIntReg(idx, val, tid); } diff --git a/src/cpu/o3/sparc/thread_context.hh b/src/cpu/o3/sparc/thread_context.hh index 3955de0cc..7497959e4 100644 --- a/src/cpu/o3/sparc/thread_context.hh +++ b/src/cpu/o3/sparc/thread_context.hh @@ -36,12 +36,6 @@ class SparcTC : public O3ThreadContext { public: #if FULL_SYSTEM - /** Returns a pointer to the ITB. */ - virtual SparcISA::ITB *getITBPtr() { return this->cpu->itb; } - - /** Returns a pointer to the DTB. */ - virtual SparcISA::DTB *getDTBPtr() { return this->cpu->dtb; } - /** Returns pointer to the quiesce event. */ virtual EndQuiesceEvent *getQuiesceEvent() { diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 390569c3d..0849001e8 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -66,6 +66,14 @@ class O3ThreadContext : public ThreadContext /** Pointer to the thread state that this TC corrseponds to. */ O3ThreadState *thread; +#if FULL_SYSTEM + /** Returns a pointer to the ITB. */ + virtual AlphaISA::ITB *getITBPtr() { return cpu->itb; } + + /** Returns a pointer to the DTB. */ + virtual AlphaISA::DTB *getDTBPtr() { return cpu->dtb; } +#endif + /** Returns a pointer to this CPU. */ virtual BaseCPU *getCpuPtr() { return cpu; } -- cgit v1.2.3 From 50b8cce355bc26a625e17a2651777340aa90a706 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 6 Dec 2006 11:40:41 -0500 Subject: Use the renamed register index, rather than the flattened one. --HG-- extra : convert_revision : 599650c408667bb1b8db20a6847b9e697f7b49e4 --- src/cpu/o3/sparc/dyn_inst.hh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/sparc/dyn_inst.hh b/src/cpu/o3/sparc/dyn_inst.hh index c645b832b..2d73ca8d1 100644 --- a/src/cpu/o3/sparc/dyn_inst.hh +++ b/src/cpu/o3/sparc/dyn_inst.hh @@ -139,23 +139,23 @@ class SparcDynInst : public BaseDynInst TheISA::FloatReg readFloatReg(const StaticInst *si, int idx, int width) { - return this->cpu->readFloatReg(this->_flatSrcRegIdx[idx], width); + return this->cpu->readFloatReg(this->_srcRegIdx[idx], width); } TheISA::FloatReg readFloatReg(const StaticInst *si, int idx) { - return this->cpu->readFloatReg(this->_flatSrcRegIdx[idx]); + return this->cpu->readFloatReg(this->_srcRegIdx[idx]); } TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) { - return this->cpu->readFloatRegBits(this->_flatSrcRegIdx[idx], width); + return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width); } TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx) { - return this->cpu->readFloatRegBits(this->_flatSrcRegIdx[idx]); + return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]); } /** @todo: Make results into arrays so they can handle multiple dest @@ -171,27 +171,27 @@ class SparcDynInst : public BaseDynInst void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val, int width) { - this->cpu->setFloatReg(this->_flatDestRegIdx[idx], val, width); + this->cpu->setFloatReg(this->_destRegIdx[idx], val, width); BaseDynInst::setFloatReg(si, idx, val, width); } void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val) { - this->cpu->setFloatReg(this->_flatDestRegIdx[idx], val); + this->cpu->setFloatReg(this->_destRegIdx[idx], val); BaseDynInst::setFloatReg(si, idx, val); } void setFloatRegBits(const StaticInst *si, int idx, TheISA::FloatRegBits val, int width) { - this->cpu->setFloatRegBits(this->_flatDestRegIdx[idx], val, width); + this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width); BaseDynInst::setFloatRegBits(si, idx, val); } void setFloatRegBits(const StaticInst *si, int idx, TheISA::FloatRegBits val) { - this->cpu->setFloatRegBits(this->_flatDestRegIdx[idx], val); + this->cpu->setFloatRegBits(this->_destRegIdx[idx], val); BaseDynInst::setFloatRegBits(si, idx, val); } -- cgit v1.2.3 From 0f8fd5fd689a3631a5896a1c098e6e561aa6a80e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 7 Dec 2006 18:47:33 -0500 Subject: Fix for squashing during a serializing instruction. --HG-- extra : convert_revision : 04f9131258bfb7cca1654e00273edb29bde2366b --- src/cpu/o3/rename.hh | 4 ++++ src/cpu/o3/rename_impl.hh | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 7 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index 177b9cb87..1ede6f355 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -411,6 +411,10 @@ class DefaultRename /** Whether or not rename needs to block this cycle. */ bool blockThisCycle; + /** Whether or not rename needs to resume a serialize instruction + * after squashing. */ + bool resumeSerialize; + /** The number of threads active in rename. */ unsigned numThreads; diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 84ccf6d5b..0c211b183 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -43,6 +43,7 @@ DefaultRename::DefaultRename(Params *params) commitToRenameDelay(params->commitToRenameDelay), renameWidth(params->renameWidth), commitWidth(params->commitWidth), + resumeSerialize(false), numThreads(params->numberOfThreads), maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs) { @@ -334,12 +335,22 @@ DefaultRename::squash(const InstSeqNum &squash_seq_num, unsigned tid) // If it still needs to block, the blocking should happen the next // cycle and there should be space to hold everything due to the squash. if (renameStatus[tid] == Blocked || - renameStatus[tid] == Unblocking || - renameStatus[tid] == SerializeStall) { - + renameStatus[tid] == Unblocking) { toDecode->renameUnblock[tid] = 1; + resumeSerialize = false; serializeInst[tid] = NULL; + } else if (renameStatus[tid] == SerializeStall) { + if (serializeInst[tid]->seqNum <= squash_seq_num) { + DPRINTF(Rename, "Rename will resume serializing after squash\n"); + resumeSerialize = true; + assert(serializeInst[tid]); + } else { + resumeSerialize = false; + toDecode->renameUnblock[tid] = 1; + + serializeInst[tid] = NULL; + } } // Set the status to Squashing. @@ -477,6 +488,14 @@ DefaultRename::rename(bool &status_change, unsigned tid) ++renameSquashCycles; } else if (renameStatus[tid] == SerializeStall) { ++renameSerializeStallCycles; + // If we are currently in SerializeStall and resumeSerialize + // was set, then that means that we are resuming serializing + // this cycle. Tell the previous stages to block. + if (resumeSerialize) { + resumeSerialize = false; + block(tid); + toDecode->renameUnblock[tid] = false; + } } if (renameStatus[tid] == Running || @@ -1245,12 +1264,19 @@ DefaultRename::checkSignalsAndUpdate(unsigned tid) if (renameStatus[tid] == Squashing) { // Switch status to running if rename isn't being told to block or // squash this cycle. - DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n", - tid); + if (!resumeSerialize) { + DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n", + tid); - renameStatus[tid] = Running; + renameStatus[tid] = Running; + return false; + } else { + DPRINTF(Rename, "[tid:%u]: Done squashing, switching to serialize.\n", + tid); - return false; + renameStatus[tid] = SerializeStall; + return true; + } } if (renameStatus[tid] == SerializeStall) { -- cgit v1.2.3 From 97cdd5198b9c1a5b881833a71f24a22430a2b07b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 7 Dec 2006 18:49:10 -0500 Subject: Compilation fixes --HG-- extra : convert_revision : 974e91a960251a35d5ebb76c7e6c7ac330339896 --- src/cpu/o3/sparc/cpu.hh | 18 ++++++++++++++++++ src/cpu/o3/sparc/cpu_builder.cc | 4 ++-- src/cpu/o3/sparc/dyn_inst_impl.hh | 3 ++- src/cpu/o3/thread_context.hh | 4 ++-- 4 files changed, 24 insertions(+), 5 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/sparc/cpu.hh b/src/cpu/o3/sparc/cpu.hh index 73c859367..08ebd2710 100644 --- a/src/cpu/o3/sparc/cpu.hh +++ b/src/cpu/o3/sparc/cpu.hh @@ -128,6 +128,24 @@ class SparcO3CPU : public FullO3CPU */ void squashFromTC(unsigned tid); +#if FULL_SYSTEM + /** Posts an interrupt. */ + void post_interrupt(int int_num, int index); + /** HW return from error interrupt. */ + Fault hwrei(unsigned tid); + + bool simPalCheck(int palFunc, unsigned tid); + + /** Returns the Fault for any valid interrupt. */ + Fault getInterrupts(); + + /** Processes any an interrupt fault. */ + void processInterrupts(Fault interrupt); + + /** Halts the CPU. */ + void halt() { panic("Halt not implemented!\n"); } +#endif + /** Traps to handle given fault. */ void trap(Fault fault, unsigned tid); diff --git a/src/cpu/o3/sparc/cpu_builder.cc b/src/cpu/o3/sparc/cpu_builder.cc index 81f419ee0..3cac89bad 100644 --- a/src/cpu/o3/sparc/cpu_builder.cc +++ b/src/cpu/o3/sparc/cpu_builder.cc @@ -55,8 +55,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU) #if FULL_SYSTEM SimObjectParam system; Param cpu_id; - SimObjectParam itb; - SimObjectParam dtb; + SimObjectParam itb; + SimObjectParam dtb; Param profile; Param do_quiesce; diff --git a/src/cpu/o3/sparc/dyn_inst_impl.hh b/src/cpu/o3/sparc/dyn_inst_impl.hh index daf93d4a8..b830ee7bd 100644 --- a/src/cpu/o3/sparc/dyn_inst_impl.hh +++ b/src/cpu/o3/sparc/dyn_inst_impl.hh @@ -126,7 +126,8 @@ template bool SparcDynInst::simPalCheck(int palFunc) { - return this->cpu->simPalCheck(palFunc, this->threadNumber); + panic("simPalCheck called, but there's no PAL in SPARC!\n"); + return false; } #else template diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 0849001e8..4987d6eb4 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -68,10 +68,10 @@ class O3ThreadContext : public ThreadContext #if FULL_SYSTEM /** Returns a pointer to the ITB. */ - virtual AlphaISA::ITB *getITBPtr() { return cpu->itb; } + TheISA::ITB *getITBPtr() { return cpu->itb; } /** Returns a pointer to the DTB. */ - virtual AlphaISA::DTB *getDTBPtr() { return cpu->dtb; } + TheISA::DTB *getDTBPtr() { return cpu->dtb; } #endif /** Returns a pointer to this CPU. */ -- cgit v1.2.3 From 498e235ae0612d268001f813de6031fcdfc76de7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 7 Dec 2006 19:00:46 -0500 Subject: Fixed to take into account the misc regs that became int regs. --HG-- extra : convert_revision : b4f78f6e48fdd2f1774ba63b28615e0d2556b7b9 --- src/cpu/exetrace.cc | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index f3b9b51b2..780a0c4f7 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -141,13 +141,15 @@ Trace::InstRecord::dump(ostream &outs) outs << hex; outs << "PC = " << thread->readNextPC(); outs << " NPC = " << thread->readNextNPC(); - newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); + newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2); + //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); if(newVal != ccr) { outs << " CCR = " << newVal; ccr = newVal; } - newVal = thread->readMiscReg(SparcISA::MISCREG_Y); + newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1); + //newVal = thread->readMiscReg(SparcISA::MISCREG_Y); if(newVal != y) { outs << " Y = " << newVal; @@ -363,9 +365,13 @@ Trace::InstRecord::dump(ostream &outs) diffHtba = true; if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE)) diffPstate = true; - if(shared_data->y != thread->readMiscReg(MISCREG_Y)) + //if(shared_data->y != thread->readMiscReg(MISCREG_Y)) + if(shared_data->y != + thread->readIntReg(NumIntArchRegs + 1)) diffY = true; - if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) + //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) + if(shared_data->ccr != + thread->readIntReg(NumIntArchRegs + 2)) diffCcr = true; if(shared_data->gl != thread->readMiscReg(MISCREG_GL)) diffGl = true; @@ -375,14 +381,22 @@ Trace::InstRecord::dump(ostream &outs) diffPil = true; if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP)) diffCwp = true; - if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE)) + //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE)) + if(shared_data->cansave != + thread->readIntReg(NumIntArchRegs + 3)) diffCansave = true; + //if(shared_data->canrestore != + // thread->readMiscReg(MISCREG_CANRESTORE)) if(shared_data->canrestore != - thread->readMiscReg(MISCREG_CANRESTORE)) + thread->readMiscReg(NumIntArchRegs + 4)) diffCanrestore = true; - if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN)) + //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN)) + if(shared_data->otherwin != + thread->readIntReg(NumIntArchRegs + 5)) diffOtherwin = true; - if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN)) + //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN)) + if(shared_data->cleanwin != + thread->readMiscReg(NumIntArchRegs + 6)) diffCleanwin = true; if (diffPC || diffInst || diffRegs || diffTpc || diffTnpc || @@ -473,10 +487,12 @@ Trace::InstRecord::dump(ostream &outs) thread->readMiscReg(MISCREG_PSTATE), shared_data->pstate); printRegPair(outs, "Y", - thread->readMiscReg(MISCREG_Y), + //thread->readMiscReg(MISCREG_Y), + thread->readMiscReg(NumIntArchRegs + 1), shared_data->y); printRegPair(outs, "Ccr", - thread->readMiscReg(MISCREG_CCR), + //thread->readMiscReg(MISCREG_CCR), + thread->readMiscReg(NumIntArchRegs + 2), shared_data->ccr); printRegPair(outs, "Tl", thread->readMiscReg(MISCREG_TL), @@ -494,16 +510,20 @@ Trace::InstRecord::dump(ostream &outs) thread->readMiscReg(MISCREG_CWP), shared_data->cwp); printRegPair(outs, "Cansave", - thread->readMiscReg(MISCREG_CANSAVE), + //thread->readMiscReg(MISCREG_CANSAVE), + thread->readIntReg(NumIntArchRegs + 3), shared_data->cansave); printRegPair(outs, "Canrestore", - thread->readMiscReg(MISCREG_CANRESTORE), + //thread->readMiscReg(MISCREG_CANRESTORE), + thread->readIntReg(NumIntArchRegs + 4), shared_data->canrestore); printRegPair(outs, "Otherwin", - thread->readMiscReg(MISCREG_OTHERWIN), + //thread->readMiscReg(MISCREG_OTHERWIN), + thread->readIntReg(NumIntArchRegs + 5), shared_data->otherwin); printRegPair(outs, "Cleanwin", - thread->readMiscReg(MISCREG_CLEANWIN), + //thread->readMiscReg(MISCREG_CLEANWIN), + thread->readIntReg(NumIntArchRegs + 6), shared_data->cleanwin); outs << endl; for (int i = 1; i <= MaxTL; i++) { -- cgit v1.2.3 From 6aa06a26b7e0c1e44427aa5360cba5662f2907c9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 07:10:04 -0500 Subject: Changes to the isa_parser and affected files to fix an indexing problem with split execute instructions and miscregs aliasing with integer registers. src/arch/isa_parser.py: Rearranged things so that classes with more than one execute function treat operands properly. 1. Eliminated the CodeBlock class 2. Created a SubOperandList 3. Redefined how InstObjParams is constructed To define an InstObjParam, you can either pass in a single code literal which will be named "code", or you can pass in a dictionary of code snippets which will be substituted into the Templates. In order to get this to work, there is a new restriction that each template has only one function in it. These changes should only affect memory instructions which have regular and split execute functions. Also changed the MiscRegs so that they use the instrunctions srcReg and destReg arrays. src/arch/sparc/isa/formats/basic.isa: src/arch/sparc/isa/formats/branch.isa: src/arch/sparc/isa/formats/integerop.isa: src/arch/sparc/isa/formats/mem/basicmem.isa: src/arch/sparc/isa/formats/mem/blockmem.isa: src/arch/sparc/isa/formats/mem/util.isa: src/arch/sparc/isa/formats/nop.isa: src/arch/sparc/isa/formats/priv.isa: src/arch/sparc/isa/formats/trap.isa: Rearranged to work with new InstObjParam scheme. src/cpu/o3/sparc/dyn_inst.hh: Added functions to access the miscregs using the indexes from instructions srcReg and destReg arrays. Also changed the names of the other accessors so that they have the suffix "Operand" if they use those arrays. src/cpu/simple/base.hh: Added functions to access the miscregs using the indexes from instructions srcReg and destReg arrays. --HG-- extra : convert_revision : c91e1073138b72bcf4113a721e0ed40ec600cf2e --- src/cpu/o3/sparc/dyn_inst.hh | 70 ++++++++++++++++++++++++++++++++++---------- src/cpu/simple/base.hh | 25 ++++++++++++++++ 2 files changed, 80 insertions(+), 15 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/sparc/dyn_inst.hh b/src/cpu/o3/sparc/dyn_inst.hh index 2d73ca8d1..fda99cb6c 100644 --- a/src/cpu/o3/sparc/dyn_inst.hh +++ b/src/cpu/o3/sparc/dyn_inst.hh @@ -106,6 +106,45 @@ class SparcDynInst : public BaseDynInst this->threadNumber); } + /** Reads a miscellaneous register. */ + TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx) + { + return this->cpu->readMiscReg( + si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag, + this->threadNumber); + } + + /** Reads a misc. register, including any side-effects the read + * might have as defined by the architecture. + */ + TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx) + { + return this->cpu->readMiscRegWithEffect( + si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag, + this->threadNumber); + } + + /** Sets a misc. register. */ + void setMiscRegOperand(const StaticInst * si, + int idx, const TheISA::MiscReg &val) + { + this->instResult.integer = val; + return this->cpu->setMiscReg( + si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag, + val, this->threadNumber); + } + + /** Sets a misc. register, including any side-effects the write + * might have as defined by the architecture. + */ + void setMiscRegOperandWithEffect( + const StaticInst *si, int idx, const TheISA::MiscReg &val) + { + return this->cpu->setMiscRegWithEffect( + si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag, + val, this->threadNumber); + } + #if FULL_SYSTEM /** Calls hardware return from error interrupt. */ Fault hwrei(); @@ -130,30 +169,31 @@ class SparcDynInst : public BaseDynInst // storage (which is pretty hard to imagine they would have reason // to do). - uint64_t readIntReg(const StaticInst *si, int idx) + uint64_t readIntRegOperand(const StaticInst *si, int idx) { uint64_t val = this->cpu->readIntReg(this->_srcRegIdx[idx]); DPRINTF(Sparc, "Reading int reg %d (%d, %d) as %x\n", (int)this->_flatSrcRegIdx[idx], (int)this->_srcRegIdx[idx], idx, val); return this->cpu->readIntReg(this->_srcRegIdx[idx]); } - TheISA::FloatReg readFloatReg(const StaticInst *si, int idx, int width) + TheISA::FloatReg readFloatRegOperand(const StaticInst *si, + int idx, int width) { return this->cpu->readFloatReg(this->_srcRegIdx[idx], width); } - TheISA::FloatReg readFloatReg(const StaticInst *si, int idx) + TheISA::FloatReg readFloatRegOperand(const StaticInst *si, int idx) { return this->cpu->readFloatReg(this->_srcRegIdx[idx]); } - TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, + TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, int width) { return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width); } - TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx) + TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) { return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]); } @@ -161,38 +201,38 @@ class SparcDynInst : public BaseDynInst /** @todo: Make results into arrays so they can handle multiple dest * registers. */ - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { DPRINTF(Sparc, "Setting int reg %d (%d, %d) to %x\n", (int)this->_flatDestRegIdx[idx], (int)this->_destRegIdx[idx], idx, val); this->cpu->setIntReg(this->_destRegIdx[idx], val); - BaseDynInst::setIntReg(si, idx, val); + BaseDynInst::setIntRegOperand(si, idx, val); } - void setFloatReg(const StaticInst *si, int idx, + void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val, int width) { this->cpu->setFloatReg(this->_destRegIdx[idx], val, width); - BaseDynInst::setFloatReg(si, idx, val, width); + BaseDynInst::setFloatRegOperand(si, idx, val, width); } - void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val) + void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val) { this->cpu->setFloatReg(this->_destRegIdx[idx], val); - BaseDynInst::setFloatReg(si, idx, val); + BaseDynInst::setFloatRegOperand(si, idx, val); } - void setFloatRegBits(const StaticInst *si, int idx, + void setFloatRegOperandBits(const StaticInst *si, int idx, TheISA::FloatRegBits val, int width) { this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width); - BaseDynInst::setFloatRegBits(si, idx, val); + BaseDynInst::setFloatRegOperandBits(si, idx, val); } - void setFloatRegBits(const StaticInst *si, + void setFloatRegOperandBits(const StaticInst *si, int idx, TheISA::FloatRegBits val) { this->cpu->setFloatRegBits(this->_destRegIdx[idx], val); - BaseDynInst::setFloatRegBits(si, idx, val); + BaseDynInst::setFloatRegOperandBits(si, idx, val); } public: diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index c39bfa9cd..dd178f64d 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -303,6 +303,31 @@ class BaseSimpleCPU : public BaseCPU return thread->setMiscRegWithEffect(misc_reg, val); } + MiscReg readMiscRegOperand(const StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; + return thread->readMiscReg(reg_idx); + } + + MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; + return thread->readMiscRegWithEffect(reg_idx); + } + + void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; + return thread->setMiscReg(reg_idx, val); + } + + void setMiscRegOperandWithEffect( + const StaticInst *si, int idx, const MiscReg &val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; + return thread->setMiscRegWithEffect(reg_idx, val); + } + #if FULL_SYSTEM Fault hwrei() { return thread->hwrei(); } void ev5_trap(Fault fault) { fault->invoke(tc); } -- cgit v1.2.3 From 4d66ddbe35252d3d70a0c3d25d100672db5f1ef9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 07:22:19 -0500 Subject: Added a predicted NPC field, explicitly stored whether the instruction was predicted taken or not. --HG-- extra : convert_revision : ba668af302ca4d8a3a032e907d5058e1477f462a --- src/cpu/base_dyn_inst.hh | 47 +++++++++++++++++++++++++++++-------------- src/cpu/base_dyn_inst_impl.hh | 6 ++++-- 2 files changed, 36 insertions(+), 17 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 17e121dbf..40e780695 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -221,6 +221,12 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Predicted next PC. */ Addr predPC; + /** Predicted next NPC. */ + Addr predNPC; + + /** If this is a branch that was predicted taken */ + bool predTaken; + /** Count of total number of dynamic instructions. */ static int instcount; @@ -336,10 +342,12 @@ class BaseDynInst : public FastAlloc, public RefCounted * @param inst The binary instruction. * @param PC The PC of the instruction. * @param pred_PC The predicted next PC. + * @param pred_NPC The predicted next NPC. * @param seq_num The sequence number of the instruction. * @param cpu Pointer to the instruction's CPU. */ - BaseDynInst(TheISA::ExtMachInst inst, Addr PC, Addr pred_PC, + BaseDynInst(TheISA::ExtMachInst inst, Addr PC, + Addr pred_PC, Addr pred_NPC, InstSeqNum seq_num, ImplCPU *cpu); /** BaseDynInst constructor given a StaticInst pointer. @@ -385,26 +393,35 @@ class BaseDynInst : public FastAlloc, public RefCounted Addr readNextNPC() { return nextNPC; } /** Set the predicted target of this current instruction. */ - void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; } + void setPredTarg(Addr predicted_PC, Addr predicted_NPC) + { + predPC = predicted_PC; + predNPC = predicted_NPC; + } + + /** Returns the predicted PC immediately after the branch. */ + Addr readPredPC() { return predPC; } - /** Returns the predicted target of the branch. */ - Addr readPredTarg() { return predPC; } + /** Returns the predicted PC two instructions after the branch */ + Addr readPredNPC() { return predNPC; } /** Returns whether the instruction was predicted taken or not. */ - bool predTaken() -#if ISA_HAS_DELAY_SLOT - { return predPC != (nextPC + sizeof(TheISA::MachInst)); } -#else - { return predPC != (PC + sizeof(TheISA::MachInst)); } -#endif + bool readPredTaken() + { + return predTaken; + } + + void setPredTaken(bool predicted_taken) + { + predTaken = predicted_taken; + } /** Returns whether the instruction mispredicted. */ bool mispredicted() -#if ISA_HAS_DELAY_SLOT - { return predPC != nextNPC; } -#else - { return predPC != nextPC; } -#endif + { + return predPC != nextPC || predNPC != nextNPC; + } + // // Instruction types. Forward checks to StaticInst object. // diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh index 2f6859de2..d47384871 100644 --- a/src/cpu/base_dyn_inst_impl.hh +++ b/src/cpu/base_dyn_inst_impl.hh @@ -63,8 +63,8 @@ my_hash_t thishash; template BaseDynInst::BaseDynInst(TheISA::ExtMachInst machInst, Addr inst_PC, - Addr pred_PC, InstSeqNum seq_num, - ImplCPU *cpu) + Addr pred_PC, Addr pred_NPC, + InstSeqNum seq_num, ImplCPU *cpu) : staticInst(machInst), traceData(NULL), cpu(cpu) { seqNum = seq_num; @@ -73,6 +73,8 @@ BaseDynInst::BaseDynInst(TheISA::ExtMachInst machInst, Addr inst_PC, nextPC = PC + sizeof(TheISA::MachInst); nextNPC = nextPC + sizeof(TheISA::MachInst); predPC = pred_PC; + predNPC = pred_NPC; + predTaken = false; initVars(); } -- cgit v1.2.3 From 37b9966eb466b1655f0d4e604bafa729a3aaea6a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 07:32:06 -0500 Subject: Made branch delay slots get squashed, and passed back an NPC and NNPC to start fetching from. --HG-- extra : convert_revision : a2e4845fedf113b5a2fd92d3d28ce5b006278103 --- src/cpu/o3/comm.hh | 3 ++ src/cpu/o3/commit_impl.hh | 2 ++ src/cpu/o3/cpu.cc | 2 +- src/cpu/o3/fetch.hh | 9 ++--- src/cpu/o3/fetch_impl.hh | 73 +++++++++++++++++++-------------------- src/cpu/o3/iew_impl.hh | 24 +++++++++---- src/cpu/o3/sparc/dyn_inst.hh | 4 +-- src/cpu/o3/sparc/dyn_inst_impl.hh | 7 ++-- 8 files changed, 70 insertions(+), 54 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh index 4683c77af..d96919007 100644 --- a/src/cpu/o3/comm.hh +++ b/src/cpu/o3/comm.hh @@ -90,6 +90,7 @@ struct DefaultIEWDefaultCommit { bool squashDelaySlot[Impl::MaxThreads]; uint64_t mispredPC[Impl::MaxThreads]; uint64_t nextPC[Impl::MaxThreads]; + uint64_t nextNPC[Impl::MaxThreads]; InstSeqNum squashedSeqNum[Impl::MaxThreads]; bool includeSquashInst[Impl::MaxThreads]; @@ -121,6 +122,7 @@ struct TimeBufStruct { bool branchTaken; uint64_t mispredPC; uint64_t nextPC; + uint64_t nextNPC; unsigned branchCount; }; @@ -160,6 +162,7 @@ struct TimeBufStruct { bool branchTaken; uint64_t mispredPC; uint64_t nextPC; + uint64_t nextNPC; // Represents the instruction that has either been retired or // squashed. Similar to having a single bus that broadcasts the diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 3178410a8..194138efc 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -514,6 +514,7 @@ DefaultCommit::squashAll(unsigned tid) toIEW->commitInfo[tid].branchMispredict = false; toIEW->commitInfo[tid].nextPC = PC[tid]; + toIEW->commitInfo[tid].nextNPC = nextPC[tid]; } template @@ -770,6 +771,7 @@ DefaultCommit::commit() fromIEW->branchTaken[tid]; toIEW->commitInfo[tid].nextPC = fromIEW->nextPC[tid]; + toIEW->commitInfo[tid].nextNPC = fromIEW->nextNPC[tid]; toIEW->commitInfo[tid].mispredPC = fromIEW->mispredPC[tid]; diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 4056d876f..5616ba398 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -700,7 +700,7 @@ FullO3CPU::removeThread(unsigned tid) // Squash Throughout Pipeline InstSeqNum squash_seq_num = commit.rob->readHeadInst(tid)->seqNum; - fetch.squash(0, squash_seq_num, true, tid); + fetch.squash(0, sizeof(TheISA::MachInst), squash_seq_num, true, tid); decode.squash(tid); rename.squash(squash_seq_num, tid); iew.squash(tid); diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 04016347a..4f5a161e0 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -239,13 +239,13 @@ class DefaultFetch bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid); /** Squashes a specific thread and resets the PC. */ - inline void doSquash(const Addr &new_PC, unsigned tid); + inline void doSquash(const Addr &new_PC, const Addr &new_NPC, unsigned tid); /** Squashes a specific thread and resets the PC. Also tells the CPU to * remove any instructions between fetch and decode that should be sqaushed. */ - void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num, - unsigned tid); + void squashFromDecode(const Addr &new_PC, const Addr &new_NPC, + const InstSeqNum &seq_num, unsigned tid); /** Checks if a thread is stalled. */ bool checkStall(unsigned tid) const; @@ -259,7 +259,8 @@ class DefaultFetch * remove any instructions that are not in the ROB. The source of this * squash should be the commit stage. */ - void squash(const Addr &new_PC, const InstSeqNum &seq_num, + void squash(const Addr &new_PC, const Addr &new_NPC, + const InstSeqNum &seq_num, bool squash_delay_slot, unsigned tid); /** Ticks the fetch stage, processing all inputs signals and fetching diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 6cff52429..5cd2e3514 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -319,9 +319,7 @@ DefaultFetch::initStage() for (int tid = 0; tid < numThreads; tid++) { PC[tid] = cpu->readPC(tid); nextPC[tid] = cpu->readNextPC(tid); -#if ISA_HAS_DELAY_SLOT nextNPC[tid] = cpu->readNextNPC(tid); -#endif } // Size of cache block. @@ -504,14 +502,14 @@ DefaultFetch::lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC, if (!inst->isControl()) { #if ISA_HAS_DELAY_SLOT - Addr cur_PC = next_PC; - next_PC = cur_PC + instSize; //next_NPC; - next_NPC = cur_PC + (2 * instSize);//next_NPC + instSize; - inst->setPredTarg(next_NPC); + next_PC = next_NPC; + next_NPC = next_NPC + instSize; + inst->setPredTarg(next_PC, next_NPC); #else next_PC = next_PC + instSize; - inst->setPredTarg(next_PC); + inst->setPredTarg(next_PC, next_PC + sizeof(TheISA::MachInst)); #endif + inst->setPredTaken(false); return false; } @@ -521,36 +519,29 @@ DefaultFetch::lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC, predict_taken = branchPred.predict(inst, pred_PC, tid); if (predict_taken) { - DPRINTF(Fetch, "[tid:%i]: Branch predicted to be true.\n", tid); + DPRINTF(Fetch, "[tid:%i]: Branch predicted to be taken.\n", tid); } else { - DPRINTF(Fetch, "[tid:%i]: Branch predicted to be false.\n", tid); + DPRINTF(Fetch, "[tid:%i]: Branch predicted to be not taken.\n", tid); } + next_PC = next_NPC; if (predict_taken) { - next_PC = next_NPC; next_NPC = pred_PC; - // Update delay slot info ++delaySlotInfo[tid].numInsts; delaySlotInfo[tid].targetAddr = pred_PC; DPRINTF(Fetch, "[tid:%i]: %i delay slot inst(s) to process.\n", tid, delaySlotInfo[tid].numInsts); - } else { // !predict_taken - if (inst->isCondDelaySlot()) { - next_PC = pred_PC; - // The delay slot is skipped here if there is on - // prediction - } else { - next_PC = next_NPC; - // No need to declare a delay slot here since - // there is no for the pred. target to jump - } - + } else { next_NPC = next_NPC + instSize; } #else predict_taken = branchPred.predict(inst, next_PC, tid); #endif + DPRINTF(Fetch, "[tid:%i]: Branch predicted to go to %#x and then %#x.\n", + tid, next_PC, next_NPC); + inst->setPredTarg(next_PC, next_NPC); + inst->setPredTaken(predict_taken); ++fetchedBranches; @@ -671,14 +662,15 @@ DefaultFetch::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid template inline void -DefaultFetch::doSquash(const Addr &new_PC, unsigned tid) +DefaultFetch::doSquash(const Addr &new_PC, + const Addr &new_NPC, unsigned tid) { - DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %#x.\n", - tid, new_PC); + DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %#x, NPC to: %#x.\n", + tid, new_PC, new_NPC); PC[tid] = new_PC; - nextPC[tid] = new_PC + instSize; - nextNPC[tid] = new_PC + (2 * instSize); + nextPC[tid] = new_NPC; + nextNPC[tid] = new_NPC + instSize; // Clear the icache miss if it's outstanding. if (fetchStatus[tid] == IcacheWaitResponse) { @@ -704,13 +696,13 @@ DefaultFetch::doSquash(const Addr &new_PC, unsigned tid) template void -DefaultFetch::squashFromDecode(const Addr &new_PC, +DefaultFetch::squashFromDecode(const Addr &new_PC, const Addr &new_NPC, const InstSeqNum &seq_num, unsigned tid) { DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid); - doSquash(new_PC, tid); + doSquash(new_PC, new_NPC, tid); #if ISA_HAS_DELAY_SLOT if (seq_num <= delaySlotInfo[tid].branchSeqNum) { @@ -793,12 +785,13 @@ DefaultFetch::updateFetchStatus() template void -DefaultFetch::squash(const Addr &new_PC, const InstSeqNum &seq_num, +DefaultFetch::squash(const Addr &new_PC, const Addr &new_NPC, + const InstSeqNum &seq_num, bool squash_delay_slot, unsigned tid) { DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid); - doSquash(new_PC, tid); + doSquash(new_PC, new_NPC, tid); #if ISA_HAS_DELAY_SLOT if (seq_num <= delaySlotInfo[tid].branchSeqNum) { @@ -928,6 +921,7 @@ DefaultFetch::checkSignalsAndUpdate(unsigned tid) #endif // In any case, squash. squash(fromCommit->commitInfo[tid].nextPC, + fromCommit->commitInfo[tid].nextNPC, doneSeqNum, fromCommit->commitInfo[tid].squashDelaySlot, tid); @@ -985,6 +979,7 @@ DefaultFetch::checkSignalsAndUpdate(unsigned tid) #endif // Squash unless we're already squashing squashFromDecode(fromDecode->decodeInfo[tid].nextPC, + fromDecode->decodeInfo[tid].nextNPC, doneSeqNum, tid); @@ -1041,6 +1036,8 @@ DefaultFetch::fetch(bool &status_change) // The current PC. Addr &fetch_PC = PC[tid]; + Addr &fetch_NPC = nextPC[tid]; + // Fault code for memory access. Fault fault = NoFault; @@ -1097,7 +1094,8 @@ DefaultFetch::fetch(bool &status_change) } Addr next_PC = fetch_PC; - Addr next_NPC = next_PC + instSize; + Addr next_NPC = fetch_NPC; + InstSeqNum inst_seq; MachInst inst; ExtMachInst ext_inst; @@ -1144,8 +1142,9 @@ DefaultFetch::fetch(bool &status_change) #endif // Create a new DynInst from the instruction fetched. - DynInstPtr instruction = new DynInst(ext_inst, fetch_PC, - next_PC, + DynInstPtr instruction = new DynInst(ext_inst, + fetch_PC, fetch_NPC, + next_PC, next_NPC, inst_seq, cpu); instruction->setTid(tid); @@ -1243,9 +1242,9 @@ DefaultFetch::fetch(bool &status_change) if (delaySlotInfo[tid].targetReady && delaySlotInfo[tid].numInsts == 0) { // Set PC to target - PC[tid] = delaySlotInfo[tid].targetAddr; //next_PC - nextPC[tid] = next_PC + instSize; //next_NPC - nextNPC[tid] = next_PC + (2 * instSize); + PC[tid] = next_PC; + nextPC[tid] = next_NPC; + nextNPC[tid] = next_NPC + instSize; delaySlotInfo[tid].targetReady = false; } else { diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index 85db68576..24c8484b4 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -481,25 +481,28 @@ DefaultIEW::squashDueToBranch(DynInstPtr &inst, unsigned tid) toCommit->branchMispredict[tid] = true; #if ISA_HAS_DELAY_SLOT + int instSize = sizeof(TheISA::MachInst); bool branch_taken = - (inst->readNextNPC() != (inst->readPC() + 2 * sizeof(TheISA::MachInst)) && - inst->readNextNPC() != (inst->readPC() + 3 * sizeof(TheISA::MachInst))); + !(inst->readNextPC() + instSize == inst->readNextNPC() && + (inst->readNextPC() == inst->readPC() + instSize || + inst->readNextPC() == inst->readPC() + 2 * instSize)); DPRINTF(Sparc, "Branch taken = %s [sn:%i]\n", branch_taken ? "true": "false", inst->seqNum); toCommit->branchTaken[tid] = branch_taken; - bool squashDelaySlot = - (inst->readNextPC() != inst->readPC() + sizeof(TheISA::MachInst)); + bool squashDelaySlot = true; +// (inst->readNextPC() != inst->readPC() + sizeof(TheISA::MachInst)); DPRINTF(Sparc, "Squash delay slot = %s [sn:%i]\n", squashDelaySlot ? "true": "false", inst->seqNum); toCommit->squashDelaySlot[tid] = squashDelaySlot; //If we're squashing the delay slot, we need to pick back up at NextPC. //Otherwise, NextPC isn't being squashed, so we should pick back up at //NextNPC. - if (squashDelaySlot) + if (squashDelaySlot) { toCommit->nextPC[tid] = inst->readNextPC(); - else + toCommit->nextNPC[tid] = inst->readNextNPC(); + } else toCommit->nextPC[tid] = inst->readNextNPC(); #else toCommit->branchTaken[tid] = inst->readNextPC() != @@ -522,6 +525,9 @@ DefaultIEW::squashDueToMemOrder(DynInstPtr &inst, unsigned tid) toCommit->squash[tid] = true; toCommit->squashedSeqNum[tid] = inst->seqNum; toCommit->nextPC[tid] = inst->readNextPC(); +#if ISA_HAS_DELAY_SLOT + toCommit->nextNPC[tid] = inst->readNextNPC(); +#endif toCommit->includeSquashInst[tid] = false; @@ -538,6 +544,9 @@ DefaultIEW::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid) toCommit->squash[tid] = true; toCommit->squashedSeqNum[tid] = inst->seqNum; toCommit->nextPC[tid] = inst->readPC(); +#if ISA_HAS_DELAY_SLOT + toCommit->nextNPC[tid] = inst->readNextNPC(); +#endif // Must include the broadcasted SN in the squash. toCommit->includeSquashInst[tid] = true; @@ -1342,6 +1351,7 @@ DefaultIEW::executeInsts() fetchRedirect[tid] = true; DPRINTF(IEW, "Execute: Branch mispredict detected.\n"); + DPRINTF(IEW, "Predicted target was %#x.\n", inst->predPC); #if ISA_HAS_DELAY_SLOT DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n", inst->nextNPC); @@ -1352,7 +1362,7 @@ DefaultIEW::executeInsts() // If incorrect, then signal the ROB that it must be squashed. squashDueToBranch(inst, tid); - if (inst->predTaken()) { + if (inst->readPredTaken()) { predictedTakenIncorrect++; } else { predictedNotTakenIncorrect++; diff --git a/src/cpu/o3/sparc/dyn_inst.hh b/src/cpu/o3/sparc/dyn_inst.hh index fda99cb6c..e95ae2fd5 100644 --- a/src/cpu/o3/sparc/dyn_inst.hh +++ b/src/cpu/o3/sparc/dyn_inst.hh @@ -56,8 +56,8 @@ class SparcDynInst : public BaseDynInst public: /** BaseDynInst constructor given a binary instruction. */ - SparcDynInst(TheISA::ExtMachInst inst, Addr PC, - Addr Pred_PC, InstSeqNum seq_num, O3CPU *cpu); + SparcDynInst(TheISA::ExtMachInst inst, Addr PC, Addr NPC, + Addr Pred_PC, Addr Pred_NPC, InstSeqNum seq_num, O3CPU *cpu); /** BaseDynInst constructor given a static inst pointer. */ SparcDynInst(StaticInstPtr &_staticInst); diff --git a/src/cpu/o3/sparc/dyn_inst_impl.hh b/src/cpu/o3/sparc/dyn_inst_impl.hh index b830ee7bd..c4d30b6f4 100644 --- a/src/cpu/o3/sparc/dyn_inst_impl.hh +++ b/src/cpu/o3/sparc/dyn_inst_impl.hh @@ -31,9 +31,10 @@ #include "cpu/o3/sparc/dyn_inst.hh" template -SparcDynInst::SparcDynInst(TheISA::ExtMachInst inst, Addr PC, - Addr Pred_PC, InstSeqNum seq_num, O3CPU *cpu) - : BaseDynInst(inst, PC, Pred_PC, seq_num, cpu) +SparcDynInst::SparcDynInst(TheISA::ExtMachInst inst, + Addr PC, Addr NPC, Addr Pred_PC, Addr Pred_NPC, + InstSeqNum seq_num, O3CPU *cpu) + : BaseDynInst(inst, PC, NPC, Pred_PC, Pred_NPC, seq_num, cpu) { initVars(); } -- cgit v1.2.3 From 6413b74e4ff3ce879852162306dc18213f8562c5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 07:33:08 -0500 Subject: Make the decoder use the new setup in the dyninsts for branch prediction. --HG-- extra : convert_revision : 9a6d6c93e5b40a55774891df54d290ff557b322c --- src/cpu/o3/decode_impl.hh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh index 80b6cc4c9..aea56cc27 100644 --- a/src/cpu/o3/decode_impl.hh +++ b/src/cpu/o3/decode_impl.hh @@ -741,7 +741,7 @@ DefaultDecode::decodeInsts(unsigned tid) // Ensure that if it was predicted as a branch, it really is a // branch. - if (inst->predTaken() && !inst->isControl()) { + if (inst->readPredTaken() && !inst->isControl()) { DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n",inst->predPC, inst->nextPC + 4); @@ -760,26 +760,29 @@ DefaultDecode::decodeInsts(unsigned tid) if (inst->isDirectCtrl() && inst->isUncondCtrl()) { ++decodeBranchResolved; - if (inst->branchTarget() != inst->readPredTarg()) { + if (inst->branchTarget() != inst->readPredPC()) { ++decodeBranchMispred; // Might want to set some sort of boolean and just do // a check at the end #if !ISA_HAS_DELAY_SLOT squash(inst, inst->threadNumber); - inst->setPredTarg(inst->branchTarget()); + Addr target = inst->branchTarget(); + inst->setPredTarg(target, target + sizeof(TheISA::MachInst)); break; #else // If mispredicted as taken, then ignore delay slot // instruction... else keep delay slot and squash // after it is sent to rename - if (inst->predTaken() && inst->isCondDelaySlot()) { + if (inst->readPredTaken() && inst->isCondDelaySlot()) { DPRINTF(Decode, "[tid:%i]: Conditional delay slot inst." "[sn:%i] PC %#x mispredicted as taken.\n", tid, inst->seqNum, inst->PC); bdelayDoneSeqNum[tid] = inst->seqNum; squash(inst, inst->threadNumber); - inst->setPredTarg(inst->branchTarget()); + Addr target = inst->branchTarget(); + inst->setPredTarg(target, + target + sizeof(TheISA::MachInst)); break; } else { DPRINTF(Decode, "[tid:%i]: Misprediction detected at " @@ -798,7 +801,9 @@ DefaultDecode::decodeInsts(unsigned tid) if (squashAfterDelaySlot[tid]) { assert(!inst->isSquashed()); squash(squashInst[tid], squashInst[tid]->threadNumber); - squashInst[tid]->setPredTarg(squashInst[tid]->branchTarget()); + Addr target = squashInst[tid]->branchTarget(); + squashInst[tid]->setPredTarg(target, + target + sizeof(TheISA::MachInst)); assert(!inst->isSquashed()); break; } -- cgit v1.2.3 From 244506ae12d079e012ec40fe85b68f54d3fd91c6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 07:34:34 -0500 Subject: Make sure endian conversion is done on the memory data when it's just set to an existing buffer. --HG-- extra : convert_revision : 5a890091b6a31b5414acbf68f19e28d7122a98d7 --- src/cpu/o3/lsq_unit_impl.hh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 7ce3dc9cb..ebd9301f6 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -601,8 +601,17 @@ LSQUnit::writebackStores() TheISA::IntReg convertedData = TheISA::htog(storeQueue[storeWBIdx].data); - memcpy(inst->memData, (uint8_t *)&convertedData, - req->getSize()); + //FIXME This is a hack to get SPARC working. It, along with endianness + //in the memory system in general, need to be straightened out more + //formally. The problem is that the data's endianness is swapped when + //it's in the 64 bit data field in the store queue. The data that you + //want won't start at the beginning of the field anymore unless it was + //a 64 bit access. + memcpy(inst->memData, + (uint8_t *)&convertedData + + (TheISA::ByteOrderDiffers ? + (sizeof(TheISA::IntReg) - req->getSize()) : 0), + req->getSize()); PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast); data_pkt->dataStatic(inst->memData); @@ -616,7 +625,7 @@ LSQUnit::writebackStores() DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x " "to Addr:%#x, data:%#x [sn:%lli]\n", storeWBIdx, inst->readPC(), - req->getPaddr(), *(inst->memData), + req->getPaddr(), (int)*(inst->memData), inst->seqNum); // @todo: Remove this SC hack once the memory system handles it. -- cgit v1.2.3 From c6944e320cfa86d3f2ce628457aff4bc431e7189 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 07:35:56 -0500 Subject: Add in capability to return to unblocking after a squash. This is needed because if you don't squash -all- the instructions, you need to keep clearing out whatever is left in the skid buffer. --HG-- extra : convert_revision : 7308eda27f4366348cf5fce71ddfa4b217bc172d --- src/cpu/o3/rename.hh | 4 ++++ src/cpu/o3/rename_impl.hh | 44 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 8 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index 1ede6f355..6b4628f92 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -415,6 +415,10 @@ class DefaultRename * after squashing. */ bool resumeSerialize; + /** Whether or not rename needs to resume clearing out the skidbuffer + * after squashing. */ + bool resumeUnblocking; + /** The number of threads active in rename. */ unsigned numThreads; diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 0c211b183..7a7234965 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -44,6 +44,7 @@ DefaultRename::DefaultRename(Params *params) renameWidth(params->renameWidth), commitWidth(params->commitWidth), resumeSerialize(false), + resumeUnblocking(false), numThreads(params->numberOfThreads), maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs) { @@ -405,6 +406,9 @@ DefaultRename::squash(const InstSeqNum &squash_seq_num, unsigned tid) } slist_it++; } + resumeUnblocking = (skidBuffer[tid].size() != 0); + DPRINTF(Rename, "Resume unblocking set to %s\n", + resumeUnblocking ? "true" : "false"); #else skidBuffer[tid].clear(); #endif @@ -496,6 +500,12 @@ DefaultRename::rename(bool &status_change, unsigned tid) block(tid); toDecode->renameUnblock[tid] = false; } + } else if (renameStatus[tid] == Unblocking) { + if (resumeUnblocking) { + block(tid); + resumeUnblocking = false; + toDecode->renameUnblock[tid] = false; + } } if (renameStatus[tid] == Running || @@ -761,7 +771,17 @@ DefaultRename::skidInsert(unsigned tid) } if (skidBuffer[tid].size() > skidBufferMax) + { + typename InstQueue::iterator it; + warn("Skidbuffer contents:\n"); + for(it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++) + { + warn("[tid:%u]: %s [sn:%i].\n", tid, + (*it)->staticInst->disassemble(inst->readPC()), + (*it)->seqNum); + } panic("Skidbuffer Exceeded Max Size"); + } } template @@ -848,7 +868,10 @@ DefaultRename::block(unsigned tid) // Only signal backwards to block if the previous stages do not think // rename is already blocked. if (renameStatus[tid] != Blocked) { - if (renameStatus[tid] != Unblocking) { + // If resumeUnblocking is set, we unblocked during the squash, + // but now we're have unblocking status. We need to tell earlier + // stages to block. + if (resumeUnblocking || renameStatus[tid] != Unblocking) { toDecode->renameBlock[tid] = true; toDecode->renameUnblock[tid] = false; wroteToTimeBuffer = true; @@ -1264,18 +1287,23 @@ DefaultRename::checkSignalsAndUpdate(unsigned tid) 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 running.\n", - tid); - - renameStatus[tid] = Running; - return false; - } else { + 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; } } -- cgit v1.2.3 From f410d5f4e0348b4499f313fb3870a48183772c20 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 07:39:44 -0500 Subject: Don't have "predict" set the predicted target of the instruction. Do that explicitly when you use predict. --HG-- extra : convert_revision : 8b613bb365b31ffaef1cea9fd789abe46219bdcf --- src/cpu/o3/bpred_unit_impl.hh | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh index 477c8e4cb..dbc603082 100644 --- a/src/cpu/o3/bpred_unit_impl.hh +++ b/src/cpu/o3/bpred_unit_impl.hh @@ -233,15 +233,6 @@ BPredUnit::predict(DynInstPtr &inst, Addr &PC, unsigned tid) } } - if (pred_taken) { - // Set the PC and the instruction's predicted target. - PC = target; - inst->setPredTarg(target); - } else { - PC = PC + sizeof(MachInst); - inst->setPredTarg(PC); - } - predHist[tid].push_front(predict_record); DPRINTF(Fetch, "[tid:%i]: predHist.size(): %i\n", tid, predHist[tid].size()); -- cgit v1.2.3 From a6eb16adb424bca1a1a1d13604def2f15c8624d1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 07:47:33 -0500 Subject: Accidently "cleaned" away the NPC parameter to the constructor. --HG-- extra : convert_revision : 46670ee86000dfb171d327eb8f58555a4afb2360 --- src/cpu/base_dyn_inst.hh | 2 +- src/cpu/base_dyn_inst_impl.hh | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 40e780695..07d53d278 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -346,7 +346,7 @@ class BaseDynInst : public FastAlloc, public RefCounted * @param seq_num The sequence number of the instruction. * @param cpu Pointer to the instruction's CPU. */ - BaseDynInst(TheISA::ExtMachInst inst, Addr PC, + BaseDynInst(TheISA::ExtMachInst inst, Addr PC, Addr NPC, Addr pred_PC, Addr pred_NPC, InstSeqNum seq_num, ImplCPU *cpu); diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh index d47384871..c3d71e428 100644 --- a/src/cpu/base_dyn_inst_impl.hh +++ b/src/cpu/base_dyn_inst_impl.hh @@ -62,7 +62,8 @@ my_hash_t thishash; #endif template -BaseDynInst::BaseDynInst(TheISA::ExtMachInst machInst, Addr inst_PC, +BaseDynInst::BaseDynInst(TheISA::ExtMachInst machInst, + Addr inst_PC, Addr inst_NPC, Addr pred_PC, Addr pred_NPC, InstSeqNum seq_num, ImplCPU *cpu) : staticInst(machInst), traceData(NULL), cpu(cpu) @@ -70,7 +71,7 @@ BaseDynInst::BaseDynInst(TheISA::ExtMachInst machInst, Addr inst_PC, seqNum = seq_num; PC = inst_PC; - nextPC = PC + sizeof(TheISA::MachInst); + nextPC = inst_NPC; nextNPC = nextPC + sizeof(TheISA::MachInst); predPC = pred_PC; predNPC = pred_NPC; -- cgit v1.2.3 From 96e5086c817bb465308588d0235d7f237e8d9c8f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 09:34:20 -0500 Subject: Make fetch detect when a branch is happening, rather than trying to compute when. --HG-- extra : convert_revision : 1a8edc004570abb48e6c4cdf1b43c5699866838e --- src/cpu/o3/fetch_impl.hh | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 5cd2e3514..815935db3 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1114,15 +1114,17 @@ DefaultFetch::fetch(bool &status_change) // ended this fetch block. bool predicted_branch = false; - // Need to keep track of whether or not a delay slot - // instruction has been fetched - for (; offset < cacheBlkSize && numInst < fetchWidth && - (!predicted_branch || delaySlotInfo[tid].numInsts > 0); + !predicted_branch; ++numInst) { + // If we're branching after this instruction, quite fetching + // from the same block then. + predicted_branch = + (fetch_PC + sizeof(TheISA::MachInst) != fetch_NPC); + // Get a sequence number. inst_seq = cpu->getAndIncrementInstSeq(); @@ -1166,8 +1168,7 @@ DefaultFetch::fetch(bool &status_change) instruction->staticInst, instruction->readPC()); - predicted_branch = lookupAndUpdateNextPC(instruction, next_PC, - next_NPC); + lookupAndUpdateNextPC(instruction, next_PC, next_NPC); // Add instruction to the CPU's list of instructions. instruction->setInstListIt(cpu->addInst(instruction)); @@ -1183,6 +1184,7 @@ DefaultFetch::fetch(bool &status_change) // Move to the next instruction, unless we have a branch. fetch_PC = next_PC; + fetch_NPC = next_NPC; if (instruction->isQuiesce()) { DPRINTF(Fetch, "Quiesce instruction encountered, halting fetch!", @@ -1194,29 +1196,6 @@ DefaultFetch::fetch(bool &status_change) } offset += instSize; - -#if ISA_HAS_DELAY_SLOT - if (predicted_branch) { - delaySlotInfo[tid].branchSeqNum = inst_seq; - - DPRINTF(Fetch, "[tid:%i]: Delay slot branch set to [sn:%i]\n", - tid, inst_seq); - continue; - } else if (delaySlotInfo[tid].numInsts > 0) { - --delaySlotInfo[tid].numInsts; - - // It's OK to set PC to target of branch - if (delaySlotInfo[tid].numInsts == 0) { - delaySlotInfo[tid].targetReady = true; - - // Break the looping condition - predicted_branch = true; - } - - DPRINTF(Fetch, "[tid:%i]: %i delay slot inst(s) left to" - " process.\n", tid, delaySlotInfo[tid].numInsts); - } -#endif } if (offset >= cacheBlkSize) { @@ -1225,7 +1204,7 @@ DefaultFetch::fetch(bool &status_change) } else if (numInst >= fetchWidth) { DPRINTF(Fetch, "[tid:%i]: Done fetching, reached fetch bandwidth " "for this cycle.\n", tid); - } else if (predicted_branch && delaySlotInfo[tid].numInsts <= 0) { + } else if (predicted_branch) { DPRINTF(Fetch, "[tid:%i]: Done fetching, predicted branch " "instruction encountered.\n", tid); } -- cgit v1.2.3 From f4f00c5ae98c069f79a8b56ed93284daf7532c7e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 16 Dec 2006 09:35:09 -0500 Subject: Switch the endianness of data that's forwarded. This is the same sort of problem that was happening when stores went all the way to memory and back. --HG-- extra : convert_revision : 09fece7ae934f542e51046d33505df3f7ec0b919 --- src/cpu/o3/lsq_unit.hh | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/cpu') diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index a2e11173e..0318175c3 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -561,6 +561,12 @@ LSQUnit::read(Request *req, T &data, int load_idx) // Cast this to type T? data = storeQueue[store_idx].data >> shift_amt; + // When the data comes from the store queue entry, it's in host + // order. When it gets sent to the load, it needs to be in guest + // order so when the load converts it again, it ends up back + // in host order like the inst expects. + data = TheISA::htog(data); + assert(!load_inst->memData); load_inst->memData = new uint8_t[64]; -- cgit v1.2.3