diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/checker/cpu_impl.hh | 2 | ||||
-rw-r--r-- | src/cpu/exetrace.cc | 95 | ||||
-rw-r--r-- | src/cpu/memtest/memtest.cc | 12 | ||||
-rw-r--r-- | src/cpu/memtest/memtest.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 2 | ||||
-rw-r--r-- | src/cpu/ozone/front_end_impl.hh | 2 | ||||
-rw-r--r-- | src/cpu/ozone/lw_lsq.hh | 2 | ||||
-rw-r--r-- | src/cpu/quiesce_event.cc | 2 | ||||
-rw-r--r-- | src/cpu/simple/atomic.cc | 14 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 50 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 1 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 3 | ||||
-rw-r--r-- | src/cpu/simple_thread.hh | 20 | ||||
-rw-r--r-- | src/cpu/static_inst.cc | 7 | ||||
-rw-r--r-- | src/cpu/static_inst.hh | 22 | ||||
-rw-r--r-- | src/cpu/thread_state.cc | 4 | ||||
-rw-r--r-- | src/cpu/thread_state.hh | 10 |
17 files changed, 177 insertions, 75 deletions
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index ba34c5cfc..36c7349e6 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -200,7 +200,7 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst) validateInst(inst); curStaticInst = StaticInst::decode(makeExtMI(machInst, - thread->readPC())); + thread->getTC())); #if FULL_SYSTEM thread->setInst(machInst); diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 8b1e60aea..9d85311bb 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -60,61 +60,66 @@ Trace::InstRecord::dump(ostream &outs) if (flags[PRINT_REG_DELTA]) { #if THE_ISA == SPARC_ISA - static uint64_t regs[32] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; - static uint64_t ccr = 0; - static uint64_t y = 0; - static uint64_t floats[32]; - uint64_t newVal; - static const char * prefixes[4] = {"G", "O", "L", "I"}; - - char buf[256]; - sprintf(buf, "PC = 0x%016llx", thread->readNextPC()); - outs << buf; - sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC()); - outs << buf; - newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); - if(newVal != ccr) + //Don't print what happens for each micro-op, just print out + //once at the last op, and for regular instructions. + if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { - sprintf(buf, " CCR = 0x%016llx", newVal); + static uint64_t regs[32] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; + static uint64_t ccr = 0; + static uint64_t y = 0; + static uint64_t floats[32]; + uint64_t newVal; + static const char * prefixes[4] = {"G", "O", "L", "I"}; + + char buf[256]; + sprintf(buf, "PC = 0x%016llx", thread->readNextPC()); outs << buf; - ccr = newVal; - } - newVal = thread->readMiscReg(SparcISA::MISCREG_Y); - if(newVal != y) - { - sprintf(buf, " Y = 0x%016llx", newVal); + sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC()); outs << buf; - y = newVal; - } - for(int y = 0; y < 4; y++) - { - for(int x = 0; x < 8; x++) + newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); + if(newVal != ccr) + { + sprintf(buf, " CCR = 0x%016llx", newVal); + outs << buf; + ccr = newVal; + } + newVal = thread->readMiscReg(SparcISA::MISCREG_Y); + if(newVal != y) + { + sprintf(buf, " Y = 0x%016llx", newVal); + outs << buf; + y = newVal; + } + for(int y = 0; y < 4; y++) { - int index = x + 8 * y; - newVal = thread->readIntReg(index); - if(regs[index] != newVal) + for(int x = 0; x < 8; x++) { - sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal); - outs << buf; - regs[index] = newVal; + int index = x + 8 * y; + newVal = thread->readIntReg(index); + if(regs[index] != newVal) + { + sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal); + outs << buf; + regs[index] = newVal; + } } } - } - for(int y = 0; y < 32; y++) - { - newVal = thread->readFloatRegBits(2 * y, 64); - if(floats[y] != newVal) + for(int y = 0; y < 32; y++) { - sprintf(buf, " F%d = 0x%016llx", y, newVal); - outs << buf; - floats[y] = newVal; + newVal = thread->readFloatRegBits(2 * y, 64); + if(floats[y] != newVal) + { + sprintf(buf, " F%d = 0x%016llx", 2 * y, newVal); + outs << buf; + floats[y] = newVal; + } } + outs << endl; } - outs << endl; #endif } else if (flags[INTEL_FORMAT]) { diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc index 1e0d07f9a..91e073cf0 100644 --- a/src/cpu/memtest/memtest.cc +++ b/src/cpu/memtest/memtest.cc @@ -113,7 +113,7 @@ MemTest::MemTest(const string &name, // PhysicalMemory *check_mem, unsigned _memorySize, unsigned _percentReads, -// unsigned _percentCopies, + unsigned _percentFunctional, unsigned _percentUncacheable, unsigned _progressInterval, unsigned _percentSourceUnaligned, @@ -130,7 +130,7 @@ MemTest::MemTest(const string &name, // checkMem(check_mem), size(_memorySize), percentReads(_percentReads), -// percentCopies(_percentCopies), + percentFunctional(_percentFunctional), percentUncacheable(_percentUncacheable), progressInterval(_progressInterval), nextProgressMessage(_progressInterval), @@ -345,7 +345,7 @@ MemTest::tick() } else { paddr = ((base) ? baseAddr1 : baseAddr2) + offset; } - bool probe = (random() % 2 == 1) && !(flags & UNCACHEABLE); + bool probe = (random() % 100 < percentFunctional) && !(flags & UNCACHEABLE); //bool probe = false; paddr &= ~((1 << access_size) - 1); @@ -501,7 +501,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest) // SimObjectParam<PhysicalMemory *> check_mem; Param<unsigned> memory_size; Param<unsigned> percent_reads; -// Param<unsigned> percent_copies; + Param<unsigned> percent_functional; Param<unsigned> percent_uncacheable; Param<unsigned> progress_interval; Param<unsigned> percent_source_unaligned; @@ -520,7 +520,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest) // INIT_PARAM(check_mem, "check memory"), INIT_PARAM(memory_size, "memory size"), INIT_PARAM(percent_reads, "target read percentage"), -// INIT_PARAM(percent_copies, "target copy percentage"), + INIT_PARAM(percent_functional, "percentage of access that are functional"), INIT_PARAM(percent_uncacheable, "target uncacheable percentage"), INIT_PARAM(progress_interval, "progress report interval (in accesses)"), INIT_PARAM(percent_source_unaligned, @@ -537,7 +537,7 @@ END_INIT_SIM_OBJECT_PARAMS(MemTest) CREATE_SIM_OBJECT(MemTest) { return new MemTest(getInstanceName(), /*cache->getInterface(),*/ /*main_mem,*/ - /*check_mem,*/ memory_size, percent_reads, /*percent_copies,*/ + /*check_mem,*/ memory_size, percent_reads, percent_functional, percent_uncacheable, progress_interval, percent_source_unaligned, percent_dest_unaligned, trace_addr, max_loads, atomic); diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh index 4e88ecffd..edde4a3b2 100644 --- a/src/cpu/memtest/memtest.hh +++ b/src/cpu/memtest/memtest.hh @@ -55,7 +55,7 @@ class MemTest : public MemObject // PhysicalMemory *check_mem, unsigned _memorySize, unsigned _percentReads, -// unsigned _percentCopies, + unsigned _percentFunctional, unsigned _percentUncacheable, unsigned _progressInterval, unsigned _percentSourceUnaligned, @@ -144,7 +144,7 @@ class MemTest : public MemObject unsigned size; // size of testing memory region unsigned percentReads; // target percentage of read accesses -// unsigned percentCopies; // target percentage of copy accesses + unsigned percentFunctional; // target percentage of functional accesses unsigned percentUncacheable; int id; diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index da75bfecf..e7bf83b20 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1118,7 +1118,7 @@ DefaultFetch<Impl>::fetch(bool &status_change) inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *> (&cacheData[tid][offset])); - ext_inst = TheISA::makeExtMI(inst, fetch_PC); + ext_inst = TheISA::makeExtMI(inst, cpu->tcBase(tid)); // Create a new DynInst from the instruction fetched. DynInstPtr instruction = new DynInst(ext_inst, fetch_PC, diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index eed6de6dd..36e87ec9c 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -883,7 +883,7 @@ FrontEnd<Impl>::getInstFromCacheline() // Get the instruction from the array of the cache line. inst = htog(*reinterpret_cast<MachInst *>(&cacheData[offset])); - ExtMachInst decode_inst = TheISA::makeExtMI(inst, PC); + ExtMachInst decode_inst = TheISA::makeExtMI(inst, tc); // Create a new DynInst from the instruction fetched. DynInstPtr instruction = new DynInst(decode_inst, PC, PC+sizeof(MachInst), diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh index 8307da521..dc58a8285 100644 --- a/src/cpu/ozone/lw_lsq.hh +++ b/src/cpu/ozone/lw_lsq.hh @@ -260,7 +260,7 @@ class OzoneLWLSQ { virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1); } + { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); } virtual bool recvTiming(PacketPtr pkt); diff --git a/src/cpu/quiesce_event.cc b/src/cpu/quiesce_event.cc index 8dd20db02..fa79e6d1e 100644 --- a/src/cpu/quiesce_event.cc +++ b/src/cpu/quiesce_event.cc @@ -28,6 +28,7 @@ * Authors: Kevin Lim */ +#include "cpu/base.hh" #include "cpu/thread_context.hh" #include "cpu/quiesce_event.hh" @@ -39,6 +40,7 @@ EndQuiesceEvent::EndQuiesceEvent(ThreadContext *_tc) void EndQuiesceEvent::process() { + DPRINTF(Quiesce, "activating %s\n", tc->getCpuPtr()->name()); tc->activate(); } diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 38a8ba097..edba55b0d 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -183,11 +183,14 @@ AtomicSimpleCPU::unserialize(Checkpoint *cp, const string §ion) void AtomicSimpleCPU::resume() { - changeState(SimObject::Running); - if (thread->status() == ThreadContext::Active) { + if (_status != SwitchedOut && _status != Idle) { assert(system->getMemoryMode() == System::Atomic); - if (!tickEvent.scheduled()) - tickEvent.schedule(curTick); + + changeState(SimObject::Running); + if (thread->status() == ThreadContext::Active) { + if (!tickEvent.scheduled()) + tickEvent.schedule(curTick); + } } } @@ -448,7 +451,8 @@ AtomicSimpleCPU::tick() for (int i = 0; i < width; ++i) { numCycles++; - checkForInterrupts(); + if (!curStaticInst || !curStaticInst->isDelayedCommit()) + checkForInterrupts(); Fault fault = setupFetchRequest(ifetch_req); diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index a79d3c542..cbb3980cb 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -396,7 +396,20 @@ BaseSimpleCPU::preExecute() // decode the instruction inst = gtoh(inst); - curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC())); + //If we're not in the middle of a macro instruction + if (!curMacroStaticInst) { + StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); + if (instPtr->isMacroOp()) { + curMacroStaticInst = instPtr; + curStaticInst = curMacroStaticInst->fetchMicroOp(0); + } else { + curStaticInst = instPtr; + } + } else { + //Read the next micro op from the macro op + curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPC()); + } + traceData = Trace::getInstRecord(curTick, tc, curStaticInst, thread->readPC()); @@ -446,18 +459,35 @@ BaseSimpleCPU::advancePC(Fault fault) { if (fault != NoFault) { fault->invoke(tc); - } - else { - // go to the next instruction - thread->setPC(thread->readNextPC()); + } else { + //If we're at the last micro op for this instruction + if (curStaticInst->isLastMicroOp()) { + //We should be working with a macro op + assert(curMacroStaticInst); + //Close out this macro op, and clean up the + //microcode state + curMacroStaticInst = StaticInst::nullStaticInstPtr; + thread->setMicroPC(0); + thread->setNextMicroPC(1); + } + //If we're still in a macro op + if (curMacroStaticInst) { + //Advance the micro pc + thread->setMicroPC(thread->readNextMicroPC()); + //Advance the "next" micro pc. Note that there are no delay + //slots, and micro ops are "word" addressed. + thread->setNextMicroPC(thread->readNextMicroPC() + 1); + } else { + // go to the next instruction + thread->setPC(thread->readNextPC()); #if ISA_HAS_DELAY_SLOT - thread->setNextPC(thread->readNextNPC()); - thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); - assert(thread->readNextPC() != thread->readNextNPC()); + thread->setNextPC(thread->readNextNPC()); + thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); + assert(thread->readNextPC() != thread->readNextNPC()); #else - thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); + thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); #endif - + } } #if FULL_SYSTEM diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 57cfa3c2c..af6b6f835 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -128,6 +128,7 @@ class BaseSimpleCPU : public BaseCPU TheISA::IntReg dataReg; StaticInstPtr curStaticInst; + StaticInstPtr curMacroStaticInst; void checkForInterrupts(); Fault setupFetchRequest(Request *req); diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 97df0e5d5..fe6775ea4 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -427,7 +427,8 @@ TimingSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) void TimingSimpleCPU::fetch() { - checkForInterrupts(); + if (!curStaticInst || !curStaticInst->isDelayedCommit()) + checkForInterrupts(); Request *ifetch_req = new Request(); ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0); diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 6fa6500bd..fe22e6c43 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -377,6 +377,16 @@ class SimpleThread : public ThreadState regs.setPC(val); } + uint64_t readMicroPC() + { + return microPC; + } + + void setMicroPC(uint64_t val) + { + microPC = val; + } + uint64_t readNextPC() { return regs.readNextPC(); @@ -387,6 +397,16 @@ class SimpleThread : public ThreadState regs.setNextPC(val); } + uint64_t readNextMicroPC() + { + return nextMicroPC; + } + + void setNextMicroPC(uint64_t val) + { + nextMicroPC = val; + } + uint64_t readNextNPC() { return regs.readNextNPC(); diff --git a/src/cpu/static_inst.cc b/src/cpu/static_inst.cc index c311d2282..cb4a7cdf7 100644 --- a/src/cpu/static_inst.cc +++ b/src/cpu/static_inst.cc @@ -75,3 +75,10 @@ StaticInst::hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const return false; } +StaticInstPtr +StaticInst::fetchMicroOp(MicroPC micropc) +{ + panic("StaticInst::fetchMicroOp() called on instruction " + "that is not microcoded."); +} + diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 578d14191..523cfae40 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -67,6 +67,8 @@ namespace Trace { class InstRecord; } +typedef uint32_t MicroPC; + /** * Base, ISA-independent static instruction class. * @@ -139,6 +141,14 @@ class StaticInstBase : public RefCounted IsIprAccess, ///< Accesses IPRs IsUnverifiable, ///< Can't be verified by a checker + //Flags for microcode + IsMacroOp, ///< Is a macroop containing microops + IsMicroOp, ///< Is a microop + IsDelayedCommit, ///< This microop doesn't commit right away + IsLastMicroOp, ///< This microop ends a microop sequence + //This flag doesn't do anything yet + IsMicroBranch, ///< This microop branches within the microcode for a macroop + NumFlags }; @@ -230,6 +240,12 @@ class StaticInstBase : public RefCounted bool isQuiesce() const { return flags[IsQuiesce]; } bool isIprAccess() const { return flags[IsIprAccess]; } bool isUnverifiable() const { return flags[IsUnverifiable]; } + bool isMacroOp() const { return flags[IsMacroOp]; } + bool isMicroOp() const { return flags[IsMicroOp]; } + bool isDelayedCommit() const { return flags[IsDelayedCommit]; } + bool isLastMicroOp() const { return flags[IsLastMicroOp]; } + //This flag doesn't do anything yet + bool isMicroBranch() const { return flags[IsMicroBranch]; } //@} /// Operation class. Used to select appropriate function unit in issue. @@ -347,6 +363,12 @@ class StaticInst : public StaticInstBase #include "cpu/static_inst_exec_sigs.hh" /** + * Return the microop that goes with a particular micropc. This should + * only be defined/used in macroops which will contain microops + */ + virtual StaticInstPtr fetchMicroOp(MicroPC micropc); + + /** * Return the target address for a PC-relative branch. * Invalid if not a PC-relative branch (i.e. isDirectCtrl() * should be true). diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index 6a96560f1..c644ae8d7 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -42,13 +42,13 @@ ThreadState::ThreadState(int _cpuId, int _tid) : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL), - funcExeInst(0), storeCondFailures(0) + microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) #else ThreadState::ThreadState(int _cpuId, int _tid, Process *_process, short _asid, MemObject *mem) : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), process(_process), asid(_asid), - funcExeInst(0), storeCondFailures(0) + microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) #endif { numInst = 0; diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 14e033b7f..60353760c 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -200,6 +200,16 @@ struct ThreadState { */ TheISA::MachInst inst; + /** The current microcode pc for the currently executing macro + * operation. + */ + MicroPC microPC; + + /** The next microcode pc for the currently executing macro + * operation. + */ + MicroPC nextMicroPC; + public: /** * Temporary storage to pass the source address from copy_load to |