From 15bb2480135d7192f895cfb8a3a945fa24472037 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 14 Sep 2009 21:19:40 -0700 Subject: [PATCH 001/160] Add an I/O cache to FS config even if there's just an "L2" cache. --- configs/example/fs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/example/fs.py b/configs/example/fs.py index b5be79a081..3164b6fb42 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -123,7 +123,7 @@ if options.l2cache: test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)] -if options.caches: +if options.caches or options.l2cache: test_sys.bridge.filter_ranges_a=[AddrRange(0, Addr.max)] test_sys.bridge.filter_ranges_b=[AddrRange(0, size='8GB')] test_sys.iocache = IOCache(addr_range=AddrRange(0, size='8GB')) From badb2382a86dacfecf2793fa9edd85fa17497d37 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 15 Sep 2009 01:44:48 -0400 Subject: [PATCH 002/160] inorder-alpha-fs: edit inorder model to compile FS mode --- src/cpu/inorder/SConscript | 1 + src/cpu/inorder/cpu.cc | 105 +++++++++++++++++++++++-- src/cpu/inorder/cpu.hh | 41 +++++++++- src/cpu/inorder/inorder_cpu_builder.cc | 5 ++ src/cpu/inorder/inorder_dyn_inst.cc | 28 +++++++ src/cpu/inorder/inorder_dyn_inst.hh | 16 ++++ src/cpu/inorder/thread_context.cc | 69 +++++++++++++--- src/cpu/inorder/thread_context.hh | 40 ++++++++++ src/cpu/inorder/thread_state.cc | 47 +++++++++++ src/cpu/inorder/thread_state.hh | 26 +++++- 10 files changed, 354 insertions(+), 24 deletions(-) create mode 100644 src/cpu/inorder/thread_state.cc diff --git a/src/cpu/inorder/SConscript b/src/cpu/inorder/SConscript index 64f1b54810..82a1028c25 100644 --- a/src/cpu/inorder/SConscript +++ b/src/cpu/inorder/SConscript @@ -79,6 +79,7 @@ if 'InOrderCPU' in env['CPU_MODELS']: Source('resources/mult_div_unit.cc') Source('resource_pool.cc') Source('reg_dep_map.cc') + Source('thread_state.cc') Source('thread_context.cc') Source('cpu.cc') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index a2367db639..4107ac3b40 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -51,6 +51,15 @@ #include "sim/process.hh" #include "sim/stat_control.hh" +#if FULL_SYSTEM +#include "cpu/quiesce_event.hh" +#include "sim/system.hh" +#endif + +#if THE_ISA == ALPHA_ISA +#include "arch/alpha/osfpal.hh" +#endif + using namespace std; using namespace TheISA; using namespace ThePipeline; @@ -171,11 +180,16 @@ InOrderCPU::InOrderCPU(Params *params) timeBuffer(2 , 2), removeInstsThisCycle(false), activityRec(params->name, NumStages, 10, params->activity), +#if FULL_SYSTEM + system(params->system), + physmem(system->physmem), +#endif // FULL_SYSTEM switchCount(0), deferRegistration(false/*params->deferRegistration*/), stageTracing(params->stageTracing), numVirtProcs(1) { + ThreadID active_threads; cpu_params = params; resPool = new ResourcePool(this, params); @@ -183,13 +197,17 @@ InOrderCPU::InOrderCPU(Params *params) // Resize for Multithreading CPUs thread.resize(numThreads); - ThreadID active_threads = params->workload.size(); +#if FULL_SYSTEM + active_threads = 1; +#else + active_threads = params->workload.size(); if (active_threads > MaxThreads) { panic("Workload Size too large. Increase the 'MaxThreads'" "in your InOrder implementation or " "edit your workload size."); } +#endif // Bind the fetch & data ports from the resource pool. fetchPortIdx = resPool->getPortIdx(params->fetchMemPort); @@ -203,6 +221,11 @@ InOrderCPU::InOrderCPU(Params *params) } for (ThreadID tid = 0; tid < numThreads; ++tid) { +#if FULL_SYSTEM + // SMT is not supported in FS mode yet. + assert(this->numThreads == 1); + this->thread[tid] = new Thread(this, 0); +#else if (tid < (ThreadID)params->workload.size()) { DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n", tid, this->thread[tid]); @@ -214,6 +237,7 @@ InOrderCPU::InOrderCPU(Params *params) Process* dummy_proc = params->workload[0]; this->thread[tid] = new Thread(this, tid, dummy_proc); } +#endif // Setup the TC that will serve as the interface to the threads/CPU. InOrderThreadContext *tc = new InOrderThreadContext; @@ -446,13 +470,6 @@ InOrderCPU::init() resPool->init(); } -void -InOrderCPU::readFunctional(Addr addr, uint32_t &buffer) -{ - tcBase()->getMemPort()->readBlob(addr, (uint8_t*)&buffer, sizeof(uint32_t)); - buffer = gtoh(buffer); -} - void InOrderCPU::reset() { @@ -468,6 +485,61 @@ InOrderCPU::getPort(const std::string &if_name, int idx) return resPool->getPort(if_name, idx); } +#if FULL_SYSTEM +Fault +InOrderCPU::hwrei(ThreadID tid) +{ + panic("hwrei: Unimplemented"); + + return NoFault; +} + + +bool +InOrderCPU::simPalCheck(int palFunc, ThreadID tid) +{ + panic("simPalCheck: Unimplemented"); + + return true; +} + + +Fault +InOrderCPU::getInterrupts() +{ + // Check if there are any outstanding interrupts + return this->interrupts->getInterrupt(this->threadContexts[0]); +} + + +void +InOrderCPU::processInterrupts(Fault interrupt) +{ + // Check for interrupts here. For now can copy the code that + // exists within isa_fullsys_traits.hh. Also assume that thread 0 + // is the one that handles the interrupts. + // @todo: Possibly consolidate the interrupt checking code. + // @todo: Allow other threads to handle interrupts. + + assert(interrupt != NoFault); + this->interrupts->updateIntrInfo(this->threadContexts[0]); + + DPRINTF(InOrderCPU, "Interrupt %s being handled\n", interrupt->name()); + this->trap(interrupt, 0); +} + + +void +InOrderCPU::updateMemPorts() +{ + // Update all ThreadContext's memory ports (Functional/Virtual + // Ports) + ThreadID size = thread.size(); + for (ThreadID i = 0; i < size; ++i) + thread[i]->connectMemPorts(thread[i]->getTC()); +} +#endif + void InOrderCPU::trap(Fault fault, ThreadID tid, int delay) { @@ -1230,6 +1302,22 @@ InOrderCPU::wakeCPU() mainEventQueue.schedule(&tickEvent, curTick); } +#if FULL_SYSTEM + +void +InOrderCPU::wakeup() +{ + if (this->thread[0]->status() != ThreadContext::Suspended) + return; + + this->wakeCPU(); + + DPRINTF(Quiesce, "Suspended Processor woken\n"); + this->threadContexts[0]->activate(); +} +#endif + +#if !FULL_SYSTEM void InOrderCPU::syscall(int64_t callnum, ThreadID tid) { @@ -1251,6 +1339,7 @@ InOrderCPU::syscall(int64_t callnum, ThreadID tid) // Clear Non-Speculative Block Variable nonSpecInstActive[tid] = false; } +#endif void InOrderCPU::prefetch(DynInstPtr inst) diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index 75d77c8182..9fb8e0df45 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -40,6 +40,7 @@ #include "arch/isa_traits.hh" #include "arch/types.hh" +#include "arch/registers.hh" #include "base/statistics.hh" #include "base/timebuf.hh" #include "base/types.hh" @@ -297,6 +298,32 @@ class InOrderCPU : public BaseCPU /** Get a Memory Port */ Port* getPort(const std::string &if_name, int idx = 0); +#if FULL_SYSTEM + /** HW return from error interrupt. */ + Fault hwrei(ThreadID tid); + + bool simPalCheck(int palFunc, ThreadID 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"); } + + /** Update the Virt and Phys ports of all ThreadContexts to + * reflect change in memory connections. */ + void updateMemPorts(); + + /** Check if this address is a valid instruction address. */ + bool validInstAddr(Addr addr) { return true; } + + /** Check if this address is a valid data address. */ + bool validDataAddr(Addr addr) { return true; } +#endif + /** trap() - sets up a trap event on the cpuTraps to handle given fault. * trapCPU() - Traps to handle given fault */ @@ -578,8 +605,6 @@ class InOrderCPU : public BaseCPU ActivityRecorder activityRec; public: - void readFunctional(Addr addr, uint32_t &buffer); - /** Number of Active Threads in the CPU */ ThreadID numActiveThreads() { return activeThreads.size(); } @@ -597,6 +622,10 @@ class InOrderCPU : public BaseCPU /** Wakes the CPU, rescheduling the CPU if it's not already active. */ void wakeCPU(); +#if FULL_SYSTEM + virtual void wakeup(); +#endif + /** Gets a free thread id. Use if thread ids change across system. */ ThreadID getFreeTid(); @@ -622,6 +651,14 @@ class InOrderCPU : public BaseCPU return total; } +#if FULL_SYSTEM + /** Pointer to the system. */ + System *system; + + /** Pointer to physical memory. */ + PhysicalMemory *physmem; +#endif + /** The global sequence number counter. */ InstSeqNum globalSeqNum[ThePipeline::MaxThreads]; diff --git a/src/cpu/inorder/inorder_cpu_builder.cc b/src/cpu/inorder/inorder_cpu_builder.cc index 5ee7b31dbd..a19137dd8b 100644 --- a/src/cpu/inorder/inorder_cpu_builder.cc +++ b/src/cpu/inorder/inorder_cpu_builder.cc @@ -42,12 +42,17 @@ InOrderCPU * InOrderCPUParams::create() { +#if FULL_SYSTEM + // Full-system only supports a single thread for the moment. + ThreadID actual_num_threads = 1; +#else ThreadID actual_num_threads = (numThreads >= workload.size()) ? numThreads : workload.size(); if (workload.size() == 0) { fatal("Must specify at least one workload!"); } +#endif numThreads = actual_num_threads; diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index a6abb28b21..9f0927b2fb 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -297,11 +297,39 @@ InOrderDynInst::memAccess() return initiateAcc(); } + +#if FULL_SYSTEM + +Fault +InOrderDynInst::hwrei() +{ + panic("InOrderDynInst: hwrei: unimplemented\n"); + return NoFault; +} + + +void +InOrderDynInst::trap(Fault fault) +{ + this->cpu->trap(fault, this->threadNumber); +} + + +bool +InOrderDynInst::simPalCheck(int palFunc) +{ +#if THE_ISA != ALPHA_ISA + panic("simPalCheck called, but PAL only exists in Alpha!\n"); +#endif + return this->cpu->simPalCheck(palFunc, this->threadNumber); +} +#else void InOrderDynInst::syscall(int64_t callnum) { cpu->syscall(callnum, this->threadNumber); } +#endif void InOrderDynInst::prefetch(Addr addr, unsigned flags) diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index e95a6d0397..a91c6a763c 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -43,6 +43,7 @@ #include "arch/mt.hh" #include "base/fast_alloc.hh" #include "base/trace.hh" +#include "base/types.hh" #include "cpu/inorder/inorder_trace.hh" #include "config/full_system.hh" #include "cpu/thread_context.hh" @@ -55,6 +56,11 @@ #include "cpu/inorder/pipeline_traits.hh" #include "mem/packet.hh" #include "sim/system.hh" +#include "sim/faults.hh" + +#if THE_ISA==ALPHA_ISA +#include "arch/alpha/ev5.hh" +#endif /** * @file @@ -64,6 +70,7 @@ // Forward declaration. class StaticInstPtr; class ResourceRequest; +class Packet; class InOrderDynInst : public FastAlloc, public RefCounted { @@ -486,7 +493,16 @@ class InOrderDynInst : public FastAlloc, public RefCounted void setCurResSlot(unsigned slot_num) { curResSlot = slot_num; } /** Calls a syscall. */ +#if FULL_SYSTEM + /** Calls hardware return from error interrupt. */ + Fault hwrei(); + /** Traps to handle specified fault. */ + void trap(Fault fault); + bool simPalCheck(int palFunc); +#else + /** Calls a syscall. */ void syscall(int64_t callnum); +#endif void prefetch(Addr addr, unsigned flags); void writeHint(Addr addr, int size, unsigned flags); Fault copySrcTranslate(Addr src); diff --git a/src/cpu/inorder/thread_context.cc b/src/cpu/inorder/thread_context.cc index fe1a0faa1b..8247bf1fb5 100644 --- a/src/cpu/inorder/thread_context.cc +++ b/src/cpu/inorder/thread_context.cc @@ -35,18 +35,71 @@ using namespace TheISA; +#if FULL_SYSTEM + +VirtualPort * +InOrderThreadContext::getVirtPort() +{ + return thread->getVirtPort(); +} + + +void +InOrderThreadContext::dumpFuncProfile() +{ + thread->dumpFuncProfile(); +} + + +Tick +InOrderThreadContext::readLastActivate() +{ + return thread->lastActivate; +} + + +Tick +InOrderThreadContext::readLastSuspend() +{ + return thread->lastSuspend; +} + + +void +InOrderThreadContext::profileClear() +{ + thread->profileClear(); +} + + +void +InOrderThreadContext::profileSample() +{ + thread->profileSample(); +} +#endif + void InOrderThreadContext::takeOverFrom(ThreadContext *old_context) { // some things should already be set up + assert(getSystemPtr() == old_context->getSystemPtr()); +#if !FULL_SYSTEM assert(getProcessPtr() == old_context->getProcessPtr()); +#endif + + // copy over functional state setStatus(old_context->status()); copyArchRegs(old_context); +#if !FULL_SYSTEM thread->funcExeInst = old_context->readFuncExeInst(); +#endif + old_context->setStatus(ThreadContext::Halted); + thread->inSyscall = false; thread->trapPending = false; } @@ -97,8 +150,8 @@ void InOrderThreadContext::regStats(const std::string &name) { #if FULL_SYSTEM - thread->kernelStats = new Kernel::Statistics(cpu->system); - thread->kernelStats->regStats(name + ".kern"); + //thread->kernelStats = new Kernel::Statistics(cpu->system); + //thread->kernelStats->regStats(name + ".kern"); #endif ; } @@ -107,22 +160,14 @@ InOrderThreadContext::regStats(const std::string &name) void InOrderThreadContext::serialize(std::ostream &os) { -#if FULL_SYSTEM - if (thread->kernelStats) - thread->kernelStats->serialize(os); -#endif - ; + panic("serialize unimplemented"); } void InOrderThreadContext::unserialize(Checkpoint *cp, const std::string §ion) { -#if FULL_SYSTEM - if (thread->kernelStats) - thread->kernelStats->unserialize(cp, section); -#endif - ; + panic("unserialize unimplemented"); } TheISA::MachInst diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh index 327f8ac711..2489c525f1 100644 --- a/src/cpu/inorder/thread_context.hh +++ b/src/cpu/inorder/thread_context.hh @@ -101,10 +101,48 @@ class InOrderThreadContext : public ThreadContext virtual void setNextMicroPC(uint64_t val) { }; +#if FULL_SYSTEM + /** Returns a pointer to physical memory. */ + virtual PhysicalMemory *getPhysMemPtr() + { assert(0); return 0; /*return cpu->physmem;*/ } + + /** Returns a pointer to this thread's kernel statistics. */ + virtual TheISA::Kernel::Statistics *getKernelStats() + { return thread->kernelStats; } + + virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); } + + virtual VirtualPort *getVirtPort(); + + virtual void connectMemPorts(ThreadContext *tc) { thread->connectMemPorts(tc); } + + /** Dumps the function profiling information. + * @todo: Implement. + */ + virtual void dumpFuncProfile(); + + /** Reads the last tick that this thread was activated on. */ + virtual Tick readLastActivate(); + /** Reads the last tick that this thread was suspended on. */ + virtual Tick readLastSuspend(); + + /** Clears the function profiling information. */ + virtual void profileClear(); + + /** Samples the function profiling information. */ + virtual void profileSample(); + + /** Returns pointer to the quiesce event. */ + virtual EndQuiesceEvent *getQuiesceEvent() + { + return this->thread->quiesceEvent; + } +#else virtual TranslatingPort *getMemPort() { return thread->getMemPort(); } /** Returns a pointer to this thread's process. */ virtual Process *getProcessPtr() { return thread->getProcessPtr(); } +#endif /** Returns this thread's status. */ virtual Status status() const { return thread->status(); } @@ -232,9 +270,11 @@ class InOrderThreadContext : public ThreadContext * misspeculating, this is set as false. */ virtual bool misspeculating() { return false; } +#if !FULL_SYSTEM /** Executes a syscall in SE mode. */ virtual void syscall(int64_t callnum) { return cpu->syscall(callnum, thread->readTid()); } +#endif /** Reads the funcExeInst counter. */ virtual Counter readFuncExeInst() { return thread->funcExeInst; } diff --git a/src/cpu/inorder/thread_state.cc b/src/cpu/inorder/thread_state.cc new file mode 100644 index 0000000000..b3a54efb10 --- /dev/null +++ b/src/cpu/inorder/thread_state.cc @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2007 MIPS Technologies, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Korey Sewell + * + */ + +#include "arch/isa_traits.hh" +#include "cpu/exetrace.hh" +#include "cpu/inorder/thread_state.hh" +#include "cpu/inorder/cpu.hh" + +using namespace TheISA; + +#if FULL_SYSTEM +void +InOrderThreadState::dumpFuncProfile() +{ + std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); + profile->dump(tc, *os); +} +#endif + diff --git a/src/cpu/inorder/thread_state.hh b/src/cpu/inorder/thread_state.hh index 9b3b39fcb4..0571b6e04e 100644 --- a/src/cpu/inorder/thread_state.hh +++ b/src/cpu/inorder/thread_state.hh @@ -33,13 +33,23 @@ #include "arch/faults.hh" #include "arch/isa_traits.hh" +#include "base/callback.hh" +#include "base/output.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" +#include "sim/sim_exit.hh" class Event; +class InOrderCPU; + +#if FULL_SYSTEM +class EndQuiesceEvent; +class FunctionProfile; +class ProfileNode; +#else class FunctionalMemory; class Process; -class InOrderCPU; +#endif /** * Class that has various thread state, such as the status, the @@ -66,16 +76,28 @@ class InOrderThreadState : public ThreadState { */ bool trapPending; - +#if FULL_SYSTEM + InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num) + : ThreadState(reinterpret_cast(_cpu), 0/*_thread_num*/), + cpu(_cpu), inSyscall(0), trapPending(0) + { } +#else InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num, Process *_process) : ThreadState(reinterpret_cast(_cpu), 0/*_thread_num*/, _process), cpu(_cpu), inSyscall(0), trapPending(0) { } +#endif +#if !FULL_SYSTEM /** Handles the syscall. */ void syscall(int64_t callnum) { process->syscall(callnum, tc); } +#endif + +#if FULL_SYSTEM + void dumpFuncProfile(); +#endif /** Pointer to the ThreadContext of this thread. */ ThreadContext *tc; From 9900ac95b5c0e197f03e5efd8d9f840a643b32c6 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 15 Sep 2009 05:30:08 -0700 Subject: [PATCH 003/160] [mq]: x86syscalls.patch --- src/arch/x86/linux/syscalls.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 4d7bca95c2..5a425ed9a2 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -508,12 +508,12 @@ const int X86_64LinuxProcess::numSyscalls = SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc), - /* 1 */ SyscallDesc("exit", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), /* 2 */ SyscallDesc("fork", unimplementedFunc), - /* 3 */ SyscallDesc("read", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), /* 4 */ SyscallDesc("write", writeFunc), - /* 5 */ SyscallDesc("open", openFunc), - /* 6 */ SyscallDesc("close", unimplementedFunc), + /* 5 */ SyscallDesc("open", openFunc), + /* 6 */ SyscallDesc("close", closeFunc), /* 7 */ SyscallDesc("waitpid", unimplementedFunc), /* 8 */ SyscallDesc("creat", unimplementedFunc), /* 9 */ SyscallDesc("link", unimplementedFunc), From 0f569b4d9dd5b7be253d45c22e9c40f615e90ecd Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 15 Sep 2009 05:48:20 -0700 Subject: [PATCH 004/160] SPARC: Make resTemp in udivcc wide enough to hold all the bits we need. --- src/arch/sparc/isa/decoder.isa | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index e34ca033f8..ce5e34ff00 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -226,7 +226,8 @@ decode OP default Unknown::unknown() if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; else Rd = Rs1.udw / Rs2_or_imm13.udw;}}); 0x1E: IntOpCcRes::udivcc({{ - uint32_t resTemp, val2 = Rs2_or_imm13.udw; + uint64_t resTemp; + uint32_t val2 = Rs2_or_imm13.udw; int32_t overflow = 0; if(val2 == 0) fault = new DivisionByZero; else From 9b8e61beb38af081454ffd5e06d14458080b98e0 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 15 Sep 2009 22:36:47 -0700 Subject: [PATCH 005/160] Syscalls: Implement sysinfo() syscall. --- src/arch/alpha/linux/linux.hh | 15 +++++++++++++++ src/arch/alpha/linux/process.cc | 2 +- src/arch/arm/linux/linux.hh | 15 +++++++++++++++ src/arch/arm/linux/process.cc | 2 +- src/arch/mips/linux/linux.hh | 16 ++++++++++++++++ src/arch/mips/linux/process.cc | 2 +- src/arch/sparc/linux/linux.hh | 32 ++++++++++++++++++++++++++++++++ src/arch/sparc/linux/syscalls.cc | 4 ++-- src/arch/x86/linux/linux.hh | 31 +++++++++++++++++++++++++++++++ src/arch/x86/linux/syscalls.cc | 4 ++-- src/sim/syscall_emul.hh | 17 +++++++++++++++++ 11 files changed, 133 insertions(+), 7 deletions(-) diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index c622c5ef1e..e9947644cb 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -125,6 +125,21 @@ class AlphaLinux : public Linux TGT_RLIMIT_MEMLOCK = 9, TGT_RLIMIT_LOCKS = 10 }; + + typedef struct { + int64_t uptime; /* Seconds since boot */ + uint64_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t sharedram; /* Amount of shared memory */ + uint64_t bufferram; /* Memory used by buffers */ + uint64_t totalswap; /* Total swap space size */ + uint64_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint64_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; }; #endif // __ALPHA_ALPHA_LINUX_LINUX_HH__ diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 9886c7ea7e..0f09e472b7 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -440,7 +440,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 315 */ SyscallDesc("munlock", unimplementedFunc), /* 316 */ SyscallDesc("mlockall", unimplementedFunc), /* 317 */ SyscallDesc("munlockall", unimplementedFunc), - /* 318 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 318 */ SyscallDesc("sysinfo", sysinfoFunc), /* 319 */ SyscallDesc("_sysctl", unimplementedFunc), /* 320 */ SyscallDesc("was sys_idle", unimplementedFunc), /* 321 */ SyscallDesc("oldumount", unimplementedFunc), diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index d99fa8e497..b9b10a5936 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -147,6 +147,21 @@ class ArmLinux : public Linux uint64_t st_ino; } tgt_stat64; + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index 56e3588a76..a7f36e18d4 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -179,7 +179,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = { /* 113 */ SyscallDesc("vm86", unimplementedFunc), /* 114 */ SyscallDesc("wait4", unimplementedFunc), /* 115 */ SyscallDesc("swapoff", unimplementedFunc), - /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", sysinfoFunc), /* 117 */ SyscallDesc("ipc", unimplementedFunc), /* 118 */ SyscallDesc("fsync", unimplementedFunc), /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index ee81fa18f8..b30cca2fbc 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -126,6 +126,22 @@ class MipsLinux : public Linux /// assign themselves to process IDs reserved for /// the root users. static const int NUM_ROOT_PROCS = 2; + + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; #endif diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 53a24487fb..0fa3c382ac 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -238,7 +238,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 113 */ SyscallDesc("vm86", unimplementedFunc), /* 114 */ SyscallDesc("wait4", unimplementedFunc), /* 115 */ SyscallDesc("swapoff", unimplementedFunc), - /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", sysinfoFunc), /* 117 */ SyscallDesc("ipc", unimplementedFunc), /* 118 */ SyscallDesc("fsync", unimplementedFunc), /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index b1dc691ce3..1f7567d43d 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -77,6 +77,22 @@ class SparcLinux : public Linux static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x20; + + typedef struct { + int64_t uptime; /* Seconds since boot */ + uint64_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t sharedram; /* Amount of shared memory */ + uint64_t bufferram; /* Memory used by buffers */ + uint64_t totalswap; /* Total swap space size */ + uint64_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint64_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; class Sparc32Linux : public SparcLinux @@ -105,6 +121,22 @@ class Sparc32Linux : public SparcLinux uint32_t __unused4; uint32_t __unused5; } tgt_stat64; + + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; #endif diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index f4781d886d..c508039762 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -302,7 +302,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 211 */ SyscallDesc("tgkill", unimplementedFunc), //32 bit /* 212 */ SyscallDesc("waitpid", unimplementedFunc), //32 bit /* 213 */ SyscallDesc("swapoff", unimplementedFunc), - /* 214 */ SyscallDesc("sysinfo", unimplementedFunc), //32 bit + /* 214 */ SyscallDesc("sysinfo", sysinfoFunc), //32 bit /* 215 */ SyscallDesc("ipc", unimplementedFunc), //32 bit /* 216 */ SyscallDesc("sigreturn", unimplementedFunc), //32 bit /* 217 */ SyscallDesc("clone", cloneFunc), @@ -608,7 +608,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 211 */ SyscallDesc("tgkill", unimplementedFunc), /* 212 */ SyscallDesc("waitpid", unimplementedFunc), /* 213 */ SyscallDesc("swapoff", unimplementedFunc), - /* 214 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 214 */ SyscallDesc("sysinfo", sysinfoFunc), /* 215 */ SyscallDesc("ipc", unimplementedFunc), /* 216 */ SyscallDesc("sigreturn", unimplementedFunc), /* 217 */ SyscallDesc("clone", cloneFunc), diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index c2941c7692..d5bead8f3d 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -111,6 +111,22 @@ class X86Linux64 : public Linux uint64_t iov_base; // void * uint64_t iov_len; // size_t } tgt_iovec; + + typedef struct { + int64_t uptime; /* Seconds since boot */ + uint64_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t sharedram; /* Amount of shared memory */ + uint64_t bufferram; /* Memory used by buffers */ + uint64_t totalswap; /* Total swap space size */ + uint64_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint64_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; class X86Linux32 : public Linux @@ -160,6 +176,21 @@ class X86Linux32 : public Linux static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x20; + + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; }; #endif diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 5a425ed9a2..52352ee807 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -327,7 +327,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 96 */ SyscallDesc("gettimeofday", unimplementedFunc), /* 97 */ SyscallDesc("getrlimit", unimplementedFunc), /* 98 */ SyscallDesc("getrusage", unimplementedFunc), - /* 99 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 99 */ SyscallDesc("sysinfo", sysinfoFunc), /* 100 */ SyscallDesc("times", unimplementedFunc), /* 101 */ SyscallDesc("ptrace", unimplementedFunc), /* 102 */ SyscallDesc("getuid", getuidFunc), @@ -623,7 +623,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 113 */ SyscallDesc("vm86old", unimplementedFunc), /* 114 */ SyscallDesc("wait4", unimplementedFunc), /* 115 */ SyscallDesc("swapoff", unimplementedFunc), - /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", sysinfoFunc), /* 117 */ SyscallDesc("ipc", unimplementedFunc), /* 118 */ SyscallDesc("fsync", unimplementedFunc), /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 5f2ebd428d..c00edfdc61 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -59,6 +59,7 @@ #include "cpu/thread_context.hh" #include "mem/translating_port.hh" #include "mem/page_table.hh" +#include "sim/system.hh" #include "sim/process.hh" /// @@ -558,6 +559,22 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } +/// Target sysinfo() handler. +template +SyscallReturn +sysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + + TypedBufferArg sysinfo(process->getSyscallArg(tc, 0)); + + sysinfo->uptime=seconds_since_epoch; + sysinfo->totalram=process->system->memSize(); + + sysinfo.copyOut(tc->getMemPort()); + + return 0; +} /// Target chmod() handler. template From 7858a8e68f9fc8e915c812515f816e8a75921d72 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 16 Sep 2009 09:45:30 -0400 Subject: [PATCH 006/160] configs: add maxinsts option on command line -option to allow threads to run to a max_inst_any_thread which is more useful/quicker in a lot of cases then always having to figure out what tick to run your simulation to. --- configs/common/Options.py | 1 + configs/common/Simulation.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/configs/common/Options.py b/configs/common/Options.py index 0ddd2f06dd..1da831e1f7 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -38,6 +38,7 @@ parser.add_option("--fastmem", action="store_true") # Run duration options parser.add_option("-m", "--maxtick", type="int") parser.add_option("--maxtime", type="float") +parser.add_option("--maxinsts", type="int") parser.add_option("--prog_intvl", type="int") diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index d7dde241cc..23dfad6c6b 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -95,6 +95,10 @@ def run(options, root, testsys, cpu_class): for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_intvl + if options.maxinsts: + for i in xrange(np): + testsys.cpu[i].max_insts_any_thread = options.maxinsts + if cpu_class: switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i)) for i in xrange(np)] From 649917411554032c10c695a9b5d51abd858320e5 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 16 Sep 2009 09:46:26 -0400 Subject: [PATCH 007/160] inorder-configs: update se.py fix bug with 'numThreads=len(workloads)' which was counting characters of command-line not counting threads as intended. Update numThreads for inorder/o3 cases and default to 1 for all other cases. --- configs/example/se.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/configs/example/se.py b/configs/example/se.py index 67a2340cee..e7fcc82611 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -94,8 +94,9 @@ if options.errout != "": # By default, set workload to path of user-specified binary workloads = options.cmd +numThreads = 1 -if options.detailed: +if options.detailed or options.inorder: #check for SMT workload workloads = options.cmd.split(';') if len(workloads) > 1: @@ -124,11 +125,12 @@ if options.detailed: smt_process.errout = errouts[smt_idx] process += [smt_process, ] smt_idx += 1 - + numThreads = len(workloads) + (CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) CPUClass.clock = '2GHz' -CPUClass.numThreads = len(workloads) +CPUClass.numThreads = numThreads; np = options.num_cpus From 83eebe046481eeefe3ed9f63f63a87a78ae9fb03 Mon Sep 17 00:00:00 2001 From: Soumyaroop Roy Date: Wed, 16 Sep 2009 09:47:38 -0400 Subject: [PATCH 008/160] inorder-smt: remove hardcoded values allows for the 2T hello world example to work in inorder model --- src/cpu/inorder/thread_state.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/inorder/thread_state.hh b/src/cpu/inorder/thread_state.hh index 0571b6e04e..422df30aa1 100644 --- a/src/cpu/inorder/thread_state.hh +++ b/src/cpu/inorder/thread_state.hh @@ -78,13 +78,13 @@ class InOrderThreadState : public ThreadState { #if FULL_SYSTEM InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num) - : ThreadState(reinterpret_cast(_cpu), 0/*_thread_num*/), + : ThreadState(reinterpret_cast(_cpu), _thread_num), cpu(_cpu), inSyscall(0), trapPending(0) { } #else InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num, Process *_process) - : ThreadState(reinterpret_cast(_cpu), 0/*_thread_num*/, + : ThreadState(reinterpret_cast(_cpu), _thread_num, _process), cpu(_cpu), inSyscall(0), trapPending(0) { } @@ -105,7 +105,7 @@ class InOrderThreadState : public ThreadState { /** Returns a pointer to the TC of this thread. */ ThreadContext *getTC() { return tc; } - int readTid() { return 0; } + int readTid() { return threadId(); } /** Pointer to the last graduated instruction in the thread */ //DynInstPtr lastGradInst; From eec6bfaa9de23b075762a62e57e46cd3f2f977ef Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:28:01 -0700 Subject: [PATCH 009/160] X86: Fix setting the busy bit in the task descriptor in LTR. --- src/arch/x86/isa/insts/system/segmentation.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py index b83fcba954..c97f2f1529 100644 --- a/src/arch/x86/isa/insts/system/segmentation.py +++ b/src/arch/x86/isa/insts/system/segmentation.py @@ -179,7 +179,8 @@ def macroop LTR_R wrdh t3, t1, t2 wrdl tr, t1, reg wrbase tr, t3, dataSize=8 - ori t1, t1, (1 << 9) + limm t5, (1 << 9) + or t1, t1, t5 st t1, tsg, [8, t4, t0], dataSize=8 }; @@ -195,7 +196,8 @@ def macroop LTR_M wrdh t3, t1, t2 wrdl tr, t1, t5 wrbase tr, t3, dataSize=8 - ori t1, t1, (1 << 9) + limm t5, (1 << 9) + or t1, t1, t5 st t1, tsg, [8, t4, t0], dataSize=8 }; @@ -212,7 +214,8 @@ def macroop LTR_P wrdh t3, t1, t2 wrdl tr, t1, t5 wrbase tr, t3, dataSize=8 - ori t1, t1, (1 << 9) + limm t5, (1 << 9) + or t1, t1, t5 st t1, tsg, [8, t4, t0], dataSize=8 }; From 239f1dea31144d8ea35065c8e037b88298db616f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:28:30 -0700 Subject: [PATCH 010/160] X86: Fix checking the NT bit during an IRET. --- .../control_transfer/interrupts_and_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index a9ad611b74..1c06506834 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -62,7 +62,7 @@ def macroop IRET_PROT { .adjust_env oszIn64Override # Check for a nested task. This isn't supported at the moment. - rflag t1, NT + rflag t1, 14; #NT bit panic "Task switching with iret is unimplemented!", flags=(nCEZF,) #t1 = temp_RIP From 7a0ef6c36fa4f188fecfd709436dfa52bb0918d6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:28:57 -0700 Subject: [PATCH 011/160] X86: Make the imm8 member of immediate microops really 8 bits consistently. --- src/arch/x86/isa/microops/regop.isa | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index a4cb6f4cc6..a8d50f17cc 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -149,12 +149,12 @@ def template MicroRegOpImmDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(BasicExecDeclare)s @@ -203,7 +203,7 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, @@ -216,7 +216,7 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, From c876a781a592c75b38853b2ec4b7d9435f1444cf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:29:51 -0700 Subject: [PATCH 012/160] X86: Sign extend the immediate of wripi like the register version. --- src/arch/x86/isa/microops/regop.isa | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index a8d50f17cc..fd1ad69259 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -324,11 +324,12 @@ let {{ matcher.sub(src2_name, flag_code), matcher.sub(src2_name, cond_check), matcher.sub(src2_name, else_code)) + imm_name = "%simm8" % match.group("prefix") self.buildCppClasses(name + "i", Name, suffix + "Imm", - matcher.sub("imm8", code), - matcher.sub("imm8", flag_code), - matcher.sub("imm8", cond_check), - matcher.sub("imm8", else_code)) + matcher.sub(imm_name, code), + matcher.sub(imm_name, flag_code), + matcher.sub(imm_name, cond_check), + matcher.sub(imm_name, else_code)) return # If there's something optional to do with flags, generate @@ -353,13 +354,16 @@ let {{ matcher = re.compile("(? Date: Thu, 17 Sep 2009 02:56:06 -0700 Subject: [PATCH 013/160] X86: Fix the expected size of the immediate offset in MOV_MI. --- src/arch/x86/predecoder_tables.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc index 5f2b5c421e..e8c838dfb4 100644 --- a/src/arch/x86/predecoder_tables.cc +++ b/src/arch/x86/predecoder_tables.cc @@ -191,7 +191,7 @@ namespace X86ISA /* 7 */ BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, /* 8 */ BY, ZW, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -/* A */ BY, VW, BY, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , +/* A */ VW, VW, VW, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , /* B */ BY, BY, BY, BY, BY, BY, BY, BY, VW, VW, VW, VW, VW, VW, VW, VW, /* C */ BY, BY, WO, 0 , 0 , 0 , BY, ZW, EN, 0 , WO, 0 , 0 , BY, 0 , 0 , /* D */ 0 , 0 , 0 , 0 , BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , From 6f7e1961131250817f6b73f5ee8cf7902bb4bba0 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 17 Sep 2009 15:45:27 -0400 Subject: [PATCH 014/160] inorder-mdu: multiplier latency fix mdu was workign incorrectly for 4+ latency due to incorrectly assuming multiply was finished the next stage --- src/cpu/inorder/resources/mult_div_unit.cc | 32 +++++++++++++++++++++- src/cpu/inorder/resources/mult_div_unit.hh | 2 ++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc index 7592c02609..e7bd6750f8 100644 --- a/src/cpu/inorder/resources/mult_div_unit.cc +++ b/src/cpu/inorder/resources/mult_div_unit.cc @@ -91,7 +91,32 @@ MultDivUnit::freeSlot(int slot_idx) Resource::freeSlot(slot_idx); } +//@TODO: Should we push this behavior into base-class to generically +// accomodate all multicyle resources? +void +MultDivUnit::requestAgain(DynInstPtr inst, bool &service_request) +{ + ResReqPtr mult_div_req = findRequest(inst); + assert(mult_div_req); + service_request = true; + + // Check to see if this instruction is requesting the same command + // or a different one + if (mult_div_req->cmd != inst->resSched.top()->cmd) { + // If different, then update command in the request + mult_div_req->cmd = inst->resSched.top()->cmd; + DPRINTF(InOrderMDU, + "[tid:%i]: [sn:%i]: Updating the command for this instruction\n", + inst->readTid(), inst->seqNum); + } else { + // If same command, just check to see if memory access was completed + // but dont try to re-execute + DPRINTF(InOrderMDU, + "[tid:%i]: [sn:%i]: requesting this resource again\n", + inst->readTid(), inst->seqNum); + } +} int MultDivUnit::getSlot(DynInstPtr inst) { @@ -232,8 +257,13 @@ MultDivUnit::execute(int slot_num) // counting down the time { DPRINTF(InOrderMDU, "End MDU called ...\n"); - if (mult_div_req->getInst()->isExecuted()) + if (mult_div_req->getInst()->isExecuted()) { + DPRINTF(InOrderMDU, "Mult/Div finished.\n"); mult_div_req->done(); + } else { + mult_div_req->setCompleted(false); + } + } break; diff --git a/src/cpu/inorder/resources/mult_div_unit.hh b/src/cpu/inorder/resources/mult_div_unit.hh index 76180714c9..d3dd0260d4 100644 --- a/src/cpu/inorder/resources/mult_div_unit.hh +++ b/src/cpu/inorder/resources/mult_div_unit.hh @@ -82,6 +82,8 @@ class MultDivUnit : public Resource { /** Register extra resource stats */ virtual void regStats(); + void requestAgain(DynInstPtr inst, bool &try_request); + protected: /** Latency & Repeat Rate for Multiply Insts */ unsigned multRepeatRate; From b7094ec38b8ec2f4de1fdf3d60a0f5953efa3e06 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 17 Sep 2009 15:59:43 -0400 Subject: [PATCH 015/160] mips: fix command line arguments arguments were not being saved correctly into M5 memory --- src/arch/mips/linux/process.cc | 6 --- src/arch/mips/linux/process.hh | 2 - src/arch/mips/process.cc | 81 ++++++++++++++++++++++++++++++++++ src/arch/mips/process.hh | 4 +- 4 files changed, 84 insertions(+), 9 deletions(-) diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 0fa3c382ac..dde3a4efde 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -413,12 +413,6 @@ MipsLinuxProcess::MipsLinuxProcess(LiveProcessParams * params, Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) { } -void -MipsLinuxProcess::startup() -{ - MipsLiveProcess::argsInit(MachineBytes, VMPageSize); -} - SyscallDesc* MipsLinuxProcess::getDesc(int callnum) { diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh index 5afde2be11..8c45014e00 100644 --- a/src/arch/mips/linux/process.hh +++ b/src/arch/mips/linux/process.hh @@ -43,8 +43,6 @@ class MipsLinuxProcess : public MipsLiveProcess /// Constructor. MipsLinuxProcess(LiveProcessParams * params, ObjectFile *objFile); - void startup(); - virtual SyscallDesc* getDesc(int callnum); /// The target system's hostname. diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index 3e9fb7c20e..b9f608922e 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -32,9 +32,15 @@ #include "arch/mips/isa_traits.hh" #include "arch/mips/process.hh" + #include "base/loader/object_file.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" + +#include "mem/page_table.hh" + +#include "sim/process.hh" +#include "sim/process_impl.hh" #include "sim/system.hh" using namespace std; @@ -62,9 +68,84 @@ MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params, void MipsLiveProcess::startup() { + Process::startup(); + argsInit(MachineBytes, VMPageSize); } +void +MipsLiveProcess::argsInit(int intSize, int pageSize) +{ + // load object file into target memory + objFile->loadSections(initVirtMem); + + // Calculate how much space we need for arg & env arrays. + int argv_array_size = intSize * (argv.size() + 1); + int envp_array_size = intSize * (envp.size() + 1); + int arg_data_size = 0; + for (vector::size_type i = 0; i < argv.size(); ++i) { + arg_data_size += argv[i].size() + 1; + } + int env_data_size = 0; + for (vector::size_type i = 0; i < envp.size(); ++i) { + env_data_size += envp[i].size() + 1; + } + + int space_needed = + argv_array_size + envp_array_size + arg_data_size + env_data_size; + if (space_needed < 32*1024) + space_needed = 32*1024; + + // set bottom of stack + stack_min = stack_base - space_needed; + // align it + stack_min = roundDown(stack_min, pageSize); + stack_size = stack_base - stack_min; + // map memory + pTable->allocate(stack_min, roundUp(stack_size, pageSize)); + + // map out initial stack contents + // ======== + // NOTE: Using uint32_t hardcodes MIPS32 and not MIPS64 + // even if MIPS64 was intended. This is because the + // copyStringArray function templates on the parameters. + // Elegant way to check intSize and vary between 32/64? + // ======== + uint32_t argv_array_base = stack_min + intSize; // room for argc + uint32_t envp_array_base = argv_array_base + argv_array_size; + uint32_t arg_data_base = envp_array_base + envp_array_size; + uint32_t env_data_base = arg_data_base + arg_data_size; + + // write contents to stack + uint32_t argc = argv.size(); + + if (intSize == 8) + argc = htog((uint64_t)argc); + else if (intSize == 4) + argc = htog((uint32_t)argc); + else + panic("Unknown int size"); + + + initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); + + copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); + + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); + + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + setSyscallArg(tc, 0, argc); + setSyscallArg(tc, 1, argv_array_base); + tc->setIntReg(StackPointerReg, stack_min); + + Addr prog_entry = objFile->entryPoint(); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); +} + + MipsISA::IntReg MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i) { diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index 87c62330fb..b8f4de20ab 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -45,7 +45,9 @@ class MipsLiveProcess : public LiveProcess protected: MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile); - virtual void startup(); + void startup(); + + void argsInit(int intSize, int pageSize); public: MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i); From aa78db4adab413600547dc01a9f1db2fbbe8fa44 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: [PATCH 016/160] code_formatter: use __builtin__ which is correct, not __builtins__ --- src/python/m5/util/code_formatter.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/python/m5/util/code_formatter.py b/src/python/m5/util/code_formatter.py index 919a6423b9..396fe0e52f 100644 --- a/src/python/m5/util/code_formatter.py +++ b/src/python/m5/util/code_formatter.py @@ -24,6 +24,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import __builtin__ import inspect import os import re @@ -64,8 +65,8 @@ class lookup(object): if self.formatter.globals and item in self.frame.f_globals: return self.frame.f_globals[item] - if item in __builtins__: - return __builtins__[item] + if item in __builtin__.__dict__: + return __builtin__.__dict__[item] try: item = int(item) From eec67312b5990dd73c6330e74bff978ad300f780 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: [PATCH 017/160] attrdict: add pickle support to attrdict --- src/python/m5/util/attrdict.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/python/m5/util/attrdict.py b/src/python/m5/util/attrdict.py index 0b30258b9c..3336632f5b 100644 --- a/src/python/m5/util/attrdict.py +++ b/src/python/m5/util/attrdict.py @@ -45,6 +45,12 @@ class attrdict(dict): return self.__delitem__(attr) return super(attrdict, self).__delattr__(attr) + def __getstate__(self): + return dict(self) + + def __setstate__(self, state): + self.update(state) + class multiattrdict(attrdict): """Wrap attrdict so that nested attribute accesses automatically create nested dictionaries.""" From 0d58d32ad51eed32e6c7f9135b901006777fbe87 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: [PATCH 018/160] multiattrdict: make multilevel nesting work properly --- src/python/m5/util/attrdict.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/python/m5/util/attrdict.py b/src/python/m5/util/attrdict.py index 3336632f5b..8f7d596980 100644 --- a/src/python/m5/util/attrdict.py +++ b/src/python/m5/util/attrdict.py @@ -58,7 +58,7 @@ class multiattrdict(attrdict): try: return super(multiattrdict, self).__getattr__(attr) except AttributeError: - d = optiondict() + d = multiattrdict() setattr(self, attr, d) return d @@ -86,8 +86,12 @@ if __name__ == '__main__': print dir(x) print(x) + print + print "multiattrdict" x = multiattrdict() + x.x.x.x = 9 x.y.z = 9 print x print x.y print x.y.z + print x.z.z From 9a8cb7db7e86c25a755f2e2817a0385b13e3ac32 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: [PATCH 019/160] python: Move more code into m5.util allow SCons to use that code. Get rid of misc.py and just stick misc things in __init__.py Move utility functions out of SCons files and into m5.util Move utility type stuff from m5/__init__.py to m5/util/__init__.py Remove buildEnv from m5 and allow access only from m5.defines Rename AddToPath to addToPath while we're moving it to m5.util Rename read_command to readCommand while we're moving it Rename compare_versions to compareVersions while we're moving it. --HG-- rename : src/python/m5/convert.py => src/python/m5/util/convert.py rename : src/python/m5/smartdict.py => src/python/m5/util/smartdict.py --- SConstruct | 68 ++------ configs/common/Caches.py | 1 - configs/common/FSConfig.py | 2 - configs/common/Simulation.py | 31 ++-- configs/example/fs.py | 37 +++-- configs/example/memtest.py | 5 +- configs/example/ruby_se.py | 25 +-- configs/example/se.py | 24 ++- configs/splash2/cluster.py | 17 +- configs/splash2/run.py | 8 +- src/SConscript | 48 ++++-- src/arch/mips/BISystem.py | 5 +- src/arch/mips/MipsCPU.py | 5 +- src/arch/mips/MipsSystem.py | 6 +- src/arch/x86/X86TLB.py | 11 +- src/cpu/BaseCPU.py | 58 +++---- src/cpu/CheckerCPU.py | 1 - src/cpu/inorder/InOrderCPU.py | 1 - src/cpu/memtest/MemTest.py | 1 - src/cpu/o3/O3CPU.py | 8 +- src/cpu/o3/O3Checker.py | 1 - src/cpu/ozone/OzoneCPU.py | 6 +- src/cpu/ozone/OzoneChecker.py | 1 - src/cpu/ozone/SimpleOzoneCPU.py | 4 +- src/cpu/simple/AtomicSimpleCPU.py | 1 - src/cpu/simple/TimingSimpleCPU.py | 1 - src/dev/Uart.py | 1 - src/mem/Bus.py | 4 +- src/python/SConscript | 5 +- src/python/m5/SimObject.py | 79 ++++----- src/python/m5/__init__.py | 102 ++---------- src/python/m5/environment.py | 43 ----- src/python/m5/main.py | 2 +- src/python/m5/params.py | 33 ++-- src/python/m5/simulate.py | 3 + src/python/m5/ticks.py | 2 +- src/python/m5/trace.py | 2 +- src/python/m5/util/__init__.py | 155 +++++++++++++++++- src/python/m5/{ => util}/convert.py | 0 src/python/m5/util/jobfile.py | 10 +- src/python/m5/util/misc.py | 87 ---------- src/python/m5/{ => util}/smartdict.py | 0 src/sim/System.py | 5 +- tests/configs/inorder-timing.py | 2 +- tests/configs/o3-timing-mp-ruby.py | 2 +- tests/configs/o3-timing-mp.py | 2 +- tests/configs/o3-timing-ruby.py | 2 +- tests/configs/o3-timing.py | 2 +- tests/configs/t1000-simple-atomic.py | 2 +- tests/configs/tsunami-o3-dual.py | 2 +- tests/configs/tsunami-o3.py | 2 +- tests/configs/tsunami-simple-atomic-dual.py | 2 +- tests/configs/tsunami-simple-atomic.py | 2 +- tests/configs/tsunami-simple-timing-dual.py | 2 +- tests/configs/tsunami-simple-timing.py | 2 +- tests/configs/twosys-tsunami-simple-atomic.py | 2 +- tests/long/00.gzip/test.py | 2 +- tests/long/10.mcf/test.py | 2 +- tests/long/20.parser/test.py | 2 +- tests/long/30.eon/test.py | 2 +- tests/long/40.perlbmk/test.py | 2 +- tests/long/50.vortex/test.py | 2 +- tests/long/60.bzip2/test.py | 2 +- tests/long/70.twolf/test.py | 2 +- 64 files changed, 450 insertions(+), 501 deletions(-) delete mode 100644 src/python/m5/environment.py rename src/python/m5/{ => util}/convert.py (100%) delete mode 100644 src/python/m5/util/misc.py rename src/python/m5/{ => util}/smartdict.py (100%) diff --git a/SConstruct b/SConstruct index 85c5de1423..e34d60ec85 100644 --- a/SConstruct +++ b/SConstruct @@ -96,6 +96,7 @@ For more details, see: """ raise +# Global Python includes import os import re import subprocess @@ -106,55 +107,14 @@ from os.path import abspath, basename, dirname, expanduser, normpath from os.path import exists, isdir, isfile from os.path import join as joinpath, split as splitpath +# SCons includes import SCons import SCons.Node -def read_command(cmd, **kwargs): - """run the command cmd, read the results and return them - this is sorta like `cmd` in shell""" - from subprocess import Popen, PIPE, STDOUT +# M5 includes +sys.path[1:1] = [ Dir('src/python').srcnode().abspath ] - if isinstance(cmd, str): - cmd = cmd.split() - - no_exception = 'exception' in kwargs - exception = kwargs.pop('exception', None) - - kwargs.setdefault('shell', False) - kwargs.setdefault('stdout', PIPE) - kwargs.setdefault('stderr', STDOUT) - kwargs.setdefault('close_fds', True) - try: - subp = Popen(cmd, **kwargs) - except Exception, e: - if no_exception: - return exception - raise - - return subp.communicate()[0] - -# helper function: compare arrays or strings of version numbers. -# E.g., compare_version((1,3,25), (1,4,1)') -# returns -1, 0, 1 if v1 is <, ==, > v2 -def compare_versions(v1, v2): - def make_version_list(v): - if isinstance(v, (list,tuple)): - return v - elif isinstance(v, str): - return map(lambda x: int(re.match('\d+', x).group()), v.split('.')) - else: - raise TypeError - - v1 = make_version_list(v1) - v2 = make_version_list(v2) - # Compare corresponding elements of lists - for n1,n2 in zip(v1, v2): - if n1 < n2: return -1 - if n1 > n2: return 1 - # all corresponding values are equal... see if one has extra values - if len(v1) < len(v2): return -1 - if len(v1) > len(v2): return 1 - return 0 +from m5.util import compareVersions, readCommand ######################################################################## # @@ -217,7 +177,7 @@ if hgdir.exists(): # 1) Grab repository revision if we know it. cmd = "hg id -n -i -t -b" try: - hg_info = read_command(cmd, cwd=main.root.abspath).strip() + hg_info = readCommand(cmd, cwd=main.root.abspath).strip() except OSError: print mercurial_bin_not_found @@ -381,8 +341,8 @@ main.Append(CPPPATH=[Dir('ext')]) # M5_PLY is used by isa_parser.py to find the PLY package. main.Append(ENV = { 'M5_PLY' : Dir('ext/ply').abspath }) -CXX_version = read_command([main['CXX'],'--version'], exception=False) -CXX_V = read_command([main['CXX'],'-V'], exception=False) +CXX_version = readCommand([main['CXX'],'--version'], exception=False) +CXX_V = readCommand([main['CXX'],'-V'], exception=False) main['GCC'] = CXX_version and CXX_version.find('g++') >= 0 main['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0 @@ -435,7 +395,7 @@ if not main.has_key('SWIG'): Exit(1) # Check for appropriate SWIG version -swig_version = read_command(('swig', '-version'), exception='').split() +swig_version = readCommand(('swig', '-version'), exception='').split() # First 3 words should be "SWIG Version x.y.z" if len(swig_version) < 3 or \ swig_version[0] != 'SWIG' or swig_version[1] != 'Version': @@ -443,7 +403,7 @@ if len(swig_version) < 3 or \ Exit(1) min_swig_version = '1.3.28' -if compare_versions(swig_version[2], min_swig_version) < 0: +if compareVersions(swig_version[2], min_swig_version) < 0: print 'Error: SWIG version', min_swig_version, 'or newer required.' print ' Installed version:', swig_version[2] Exit(1) @@ -514,8 +474,8 @@ conf.CheckLeading() try: import platform uname = platform.uname() - if uname[0] == 'Darwin' and compare_versions(uname[2], '9.0.0') >= 0: - if int(read_command('sysctl -n hw.cpu64bit_capable')[0]): + if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0: + if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]): main.Append(CCFLAGS='-arch x86_64') main.Append(CFLAGS='-arch x86_64') main.Append(LINKFLAGS='-arch x86_64') @@ -615,9 +575,9 @@ have_mysql = bool(mysql_config) # Check MySQL version. if have_mysql: - mysql_version = read_command(mysql_config + ' --version') + mysql_version = readCommand(mysql_config + ' --version') min_mysql_version = '4.1' - if compare_versions(mysql_version, min_mysql_version) < 0: + if compareVersions(mysql_version, min_mysql_version) < 0: print 'Warning: MySQL', min_mysql_version, 'or newer required.' print ' Version', mysql_version, 'detected.' have_mysql = False diff --git a/configs/common/Caches.py b/configs/common/Caches.py index 1c3b089c79..412cfd3b14 100644 --- a/configs/common/Caches.py +++ b/configs/common/Caches.py @@ -26,7 +26,6 @@ # # Authors: Lisa Hsu -import m5 from m5.objects import * class L1Cache(BaseCache): diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index 180e0ac52e..bd20a2bacc 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -26,8 +26,6 @@ # # Authors: Kevin Lim -import m5 -from m5 import makeList from m5.objects import * from Benchmarks import * diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index 23dfad6c6b..112a951b66 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -28,9 +28,13 @@ from os import getcwd from os.path import join as joinpath + import m5 +from m5.defines import buildEnv from m5.objects import * -m5.AddToPath('../common') +from m5.util import * + +addToPath('../common') def setCPUClass(options): @@ -82,10 +86,10 @@ def run(options, root, testsys, cpu_class): cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: - m5.fatal("Error: Can't specify both --fast-forward and --checkpoint-restore") + fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: - m5.fatal("Error: Must specify --caches when using --standard-switch") + fatal("Must specify --caches when using --standard-switch") np = options.num_cpus max_checkpoints = options.max_checkpoints @@ -107,7 +111,7 @@ def run(options, root, testsys, cpu_class): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys - if not m5.build_env['FULL_SYSTEM']: + if not buildEnv['FULL_SYSTEM']: switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[0].clock # simulation period @@ -126,7 +130,7 @@ def run(options, root, testsys, cpu_class): for i in xrange(np): switch_cpus[i].system = testsys switch_cpus_1[i].system = testsys - if not m5.build_env['FULL_SYSTEM']: + if not buildEnv['FULL_SYSTEM']: switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[0].clock @@ -141,7 +145,7 @@ def run(options, root, testsys, cpu_class): # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: - m5.fatal('simpoint not found') + fatal('simpoint not found') testsys.cpu[i].max_insts_any_thread = \ testsys.cpu[i].workload[0].simpoint # No distance specified, just switch @@ -174,7 +178,7 @@ def run(options, root, testsys, cpu_class): if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: - m5.fatal('no simpoint for testsys.cpu[%d].workload[0]', i) + fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below @@ -194,14 +198,13 @@ def run(options, root, testsys, cpu_class): import re if not isdir(cptdir): - m5.fatal("checkpoint dir %s does not exist!", cptdir) + fatal("checkpoint dir %s does not exist!", cptdir) if options.at_instruction: checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % \ (options.bench, options.checkpoint_restore)) if not exists(checkpoint_dir): - m5.fatal("Unable to find checkpoint directory %s", - checkpoint_dir) + fatal("Unable to find checkpoint directory %s", checkpoint_dir) print "Restoring checkpoint ..." m5.restoreCheckpoint(root, checkpoint_dir) @@ -209,7 +212,7 @@ def run(options, root, testsys, cpu_class): elif options.simpoint: # assume workload 0 has the simpoint if testsys.cpu[0].workload[0].simpoint == 0: - m5.fatal('Unable to find simpoint') + fatal('Unable to find simpoint') options.checkpoint_restore += \ int(testsys.cpu[0].workload[0].simpoint) @@ -217,8 +220,8 @@ def run(options, root, testsys, cpu_class): checkpoint_dir = joinpath(cptdir, "cpt.%s.%d" % \ (options.bench, options.checkpoint_restore)) if not exists(checkpoint_dir): - m5.fatal("Unable to find checkpoint directory %s.%s", - options.bench, options.checkpoint_restore) + fatal("Unable to find checkpoint directory %s.%s", + options.bench, options.checkpoint_restore) print "Restoring checkpoint ..." m5.restoreCheckpoint(root,checkpoint_dir) @@ -237,7 +240,7 @@ def run(options, root, testsys, cpu_class): cpt_num = options.checkpoint_restore if cpt_num > len(cpts): - m5.fatal('Checkpoint %d not found', cpt_num) + fatal('Checkpoint %d not found', cpt_num) ## Adjust max tick based on our starting tick maxtick = maxtick - int(cpts[cpt_num - 1]) diff --git a/configs/example/fs.py b/configs/example/fs.py index 3164b6fb42..23285e1017 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -26,15 +26,20 @@ # # Authors: Ali Saidi -import optparse, os, sys +import optparse +import os +import sys import m5 - -if not m5.build_env['FULL_SYSTEM']: - m5.fatal("This script requires full-system mode (*_FS).") - +from m5.defines import buildEnv from m5.objects import * -m5.AddToPath('../common') +from m5.util import addToPath, fatal + +if not buildEnv['FULL_SYSTEM']: + fatal("This script requires full-system mode (*_FS).") + +addToPath('../common') + from FSConfig import * from SysPaths import * from Benchmarks import * @@ -98,16 +103,16 @@ else: np = options.num_cpus -if m5.build_env['TARGET_ISA'] == "alpha": +if buildEnv['TARGET_ISA'] == "alpha": test_sys = makeLinuxAlphaSystem(test_mem_mode, bm[0]) -elif m5.build_env['TARGET_ISA'] == "mips": +elif buildEnv['TARGET_ISA'] == "mips": test_sys = makeLinuxMipsSystem(test_mem_mode, bm[0]) -elif m5.build_env['TARGET_ISA'] == "sparc": +elif buildEnv['TARGET_ISA'] == "sparc": test_sys = makeSparcSystem(test_mem_mode, bm[0]) -elif m5.build_env['TARGET_ISA'] == "x86": +elif buildEnv['TARGET_ISA'] == "x86": test_sys = makeLinuxX86System(test_mem_mode, np, bm[0]) else: - m5.fatal("incapable of building non-alpha or non-sparc full system!") + fatal("incapable of building non-alpha or non-sparc full system!") if options.kernel is not None: test_sys.kernel = binary(options.kernel) @@ -142,17 +147,17 @@ for i in xrange(np): if options.fastmem: test_sys.cpu[i].physmem_port = test_sys.physmem.port -if m5.build_env['TARGET_ISA'] == 'mips': +if buildEnv['TARGET_ISA'] == 'mips': setMipsOptions(TestCPUClass) if len(bm) == 2: - if m5.build_env['TARGET_ISA'] == 'alpha': + if buildEnv['TARGET_ISA'] == 'alpha': drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1]) - elif m5.build_env['TARGET_ISA'] == 'mips': + elif buildEnv['TARGET_ISA'] == 'mips': drive_sys = makeLinuxMipsSystem(drive_mem_mode, bm[1]) - elif m5.build_env['TARGET_ISA'] == 'sparc': + elif buildEnv['TARGET_ISA'] == 'sparc': drive_sys = makeSparcSystem(drive_mem_mode, bm[1]) - elif m5.build.env['TARGET_ISA'] == 'x86': + elif buildEnv['TARGET_ISA'] == 'x86': drive_sys = makeX86System(drive_mem_mode, np, bm[1]) drive_sys.cpu = DriveCPUClass(cpu_id=0) drive_sys.cpu.connectMemPorts(drive_sys.membus) diff --git a/configs/example/memtest.py b/configs/example/memtest.py index 5bb874e854..d4497092bf 100644 --- a/configs/example/memtest.py +++ b/configs/example/memtest.py @@ -26,10 +26,11 @@ # # Authors: Ron Dreslinski +import optparse +import sys + import m5 from m5.objects import * -import os, optparse, sys -m5.AddToPath('../common') parser = optparse.OptionParser() diff --git a/configs/example/ruby_se.py b/configs/example/ruby_se.py index 488ccb64a5..76668f7631 100644 --- a/configs/example/ruby_se.py +++ b/configs/example/ruby_se.py @@ -30,17 +30,22 @@ # # "m5 test.py" -import m5 - -if m5.build_env['FULL_SYSTEM']: - m5.panic("This script requires syscall emulation mode (*_SE).") - -from m5.objects import * -import os, optparse, sys +import os +import optparse +import sys from os.path import join as joinpath -m5.AddToPath('../common') + +import m5 +from m5.defines import buildEnv +from m5.objects import * +from m5.util import addToPath, panic + +if buildEnv['FULL_SYSTEM']: + panic("This script requires syscall emulation mode (*_SE).") + +addToPath('../common') + import Simulation -#from Caches import * from cpu2000 import * # Get paths we might need. It's expected this file is in m5/configs/example. @@ -72,7 +77,7 @@ if args: if options.bench: try: - if m5.build_env['TARGET_ISA'] != 'alpha': + if buildEnv['TARGET_ISA'] != 'alpha': print >>sys.stderr, "Simpoints code only works for Alpha ISA at this time" sys.exit(1) exec("workload = %s('alpha', 'tru64', 'ref')" % options.bench) diff --git a/configs/example/se.py b/configs/example/se.py index e7fcc82611..c490ed6b61 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -30,15 +30,21 @@ # # "m5 test.py" -import m5 - -if m5.build_env['FULL_SYSTEM']: - m5.fatal("This script requires syscall emulation mode (*_SE).") - -from m5.objects import * -import os, optparse, sys +import os +import optparse +import sys from os.path import join as joinpath -m5.AddToPath('../common') + +import m5 +from m5.defines import buildEnv +from m5.objects import * +from m5.util import addToPath, fatal + +if buildEnv['FULL_SYSTEM']: + fatal("This script requires syscall emulation mode (*_SE).") + +addToPath('../common') + import Simulation from Caches import * from cpu2000 import * @@ -70,7 +76,7 @@ if args: if options.bench: try: - if m5.build_env['TARGET_ISA'] != 'alpha': + if buildEnv['TARGET_ISA'] != 'alpha': print >>sys.stderr, "Simpoints code only works for Alpha ISA at this time" sys.exit(1) exec("workload = %s('alpha', 'tru64', 'ref')" % options.bench) diff --git a/configs/splash2/cluster.py b/configs/splash2/cluster.py index 769bdcf5a9..45c9ede82b 100644 --- a/configs/splash2/cluster.py +++ b/configs/splash2/cluster.py @@ -30,10 +30,14 @@ # # "m5 test.py" +import os +import optparse +import sys + import m5 from m5.objects import * -import os, optparse, sys -m5.AddToPath('../common') + +m5.util.addToPath('../common') # -------------------- # Define Command Line Options @@ -266,10 +270,11 @@ elif options.benchmark == 'WaterNSquared': elif options.benchmark == 'WaterSpatial': root.workload = Water_spatial() else: - panic("The --benchmark environment variable was set to something" \ - +" improper.\nUse Cholesky, FFT, LUContig, LUNoncontig, Radix" \ - +", Barnes, FMM, OceanContig,\nOceanNoncontig, Raytrace," \ - +" WaterNSquared, or WaterSpatial\n") + m5.util.panic(""" +The --benchmark environment variable was set to something improper. +Use Cholesky, FFT, LUContig, LUNoncontig, Radix, Barnes, FMM, OceanContig, +OceanNoncontig, Raytrace, WaterNSquared, or WaterSpatial +""") # -------------------- # Assign the workload to the cpus diff --git a/configs/splash2/run.py b/configs/splash2/run.py index afa85a8f17..95ec790ba9 100644 --- a/configs/splash2/run.py +++ b/configs/splash2/run.py @@ -29,10 +29,14 @@ # Splash2 Run Script # +import os +import optparse +import sys + import m5 from m5.objects import * -import os, optparse, sys -m5.AddToPath('../common') + +m5.util.addToPath('../common') # -------------------- # Define Command Line Options diff --git a/src/SConscript b/src/SConscript index d96922b49e..687709ac13 100644 --- a/src/SConscript +++ b/src/SConscript @@ -49,7 +49,7 @@ Import('*') # Children need to see the environment Export('env') -build_env = dict([(opt, env[opt]) for opt in export_vars]) +build_env = [(opt, env[opt]) for opt in export_vars] ######################################################################## # Code for adding source files of various types @@ -266,6 +266,8 @@ for opt in export_vars: # Prevent any SimObjects from being added after this point, they # should all have been added in the SConscripts above # +SimObject.fixed = True + class DictImporter(object): '''This importer takes a dictionary of arbitrary module names that map to arbitrary filenames.''' @@ -283,7 +285,7 @@ class DictImporter(object): self.installed = set() def find_module(self, fullname, path): - if fullname == 'defines': + if fullname == 'm5.defines': return self if fullname == 'm5.objects': @@ -293,7 +295,7 @@ class DictImporter(object): return None source = self.modules.get(fullname, None) - if source is not None and exists(source.snode.abspath): + if source is not None and fullname.startswith('m5.objects'): return self return None @@ -308,8 +310,8 @@ class DictImporter(object): mod.__path__ = fullname.split('.') return mod - if fullname == 'defines': - mod.__dict__['buildEnv'] = build_env + if fullname == 'm5.defines': + mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) return mod source = self.modules[fullname] @@ -321,15 +323,18 @@ class DictImporter(object): return mod +import m5.SimObject +import m5.params + +m5.SimObject.clear() +m5.params.clear() + # install the python importer so we can grab stuff from the source # tree itself. We can't have SimObjects added after this point or # else we won't know about them for the rest of the stuff. -SimObject.fixed = True importer = DictImporter(PySource.modules) sys.meta_path[0:0] = [ importer ] -import m5 - # import all sim objects so we can populate the all_objects list # make sure that we're working with a list, then let's sort it for modname in SimObject.modnames: @@ -346,6 +351,12 @@ all_enums = m5.params.allEnums all_params = {} for name,obj in sorted(sim_objects.iteritems()): for param in obj._params.local.values(): + # load the ptype attribute now because it depends on the + # current version of SimObject.allClasses, but when scons + # actually uses the value, all versions of + # SimObject.allClasses will have been loaded + param.ptype + if not hasattr(param, 'swig_decl'): continue pname = param.ptype_str @@ -365,13 +376,24 @@ depends = [ PySource.modules[dep].tnode for dep in module_depends ] # # Generate Python file containing a dict specifying the current -# build_env flags. +# buildEnv flags. def makeDefinesPyFile(target, source, env): - f = file(str(target[0]), 'w') build_env, hg_info = [ x.get_contents() for x in source ] - print >>f, "buildEnv = %s" % build_env - print >>f, "hgRev = '%s'" % hg_info - f.close() + + code = m5.util.code_formatter() + code(""" +import m5.internal +import m5.util + +buildEnv = m5.util.SmartDict($build_env) +hgRev = '$hg_info' + +compileDate = m5.internal.core.compileDate +for k,v in m5.internal.core.__dict__.iteritems(): + if k.startswith('flag_'): + setattr(buildEnv, k[5:], v) +""") + code.write(str(target[0])) defines_info = [ Value(build_env), Value(env['HG_INFO']) ] # Generate a file with all of the compile options in it diff --git a/src/arch/mips/BISystem.py b/src/arch/mips/BISystem.py index dd4e4fe259..a6e4091f25 100755 --- a/src/arch/mips/BISystem.py +++ b/src/arch/mips/BISystem.py @@ -28,10 +28,11 @@ # # Authors: Jaidev Patwardhan -from m5 import build_env +from m5.defines import buildEnv + from System import * -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: class BareIronMipsSystem(MipsSystem): type = 'BareIronMipsSystem' system_type = 34 diff --git a/src/arch/mips/MipsCPU.py b/src/arch/mips/MipsCPU.py index 81c6bdacf6..48ee4171c7 100644 --- a/src/arch/mips/MipsCPU.py +++ b/src/arch/mips/MipsCPU.py @@ -29,12 +29,13 @@ # Authors: Jaidev Patwardhan # Korey Sewell -from m5.SimObject import SimObject +from m5.defines import buildEnv from m5.params import * + from BaseCPU import BaseCPU class BaseMipsCPU(BaseCPU) - if build_env['TARGET_ISA'] == 'mips': + if buildEnv['TARGET_ISA'] == 'mips': CP0_IntCtl_IPTI = Param.Unsigned(0,"No Description") CP0_IntCtl_IPPCI = Param.Unsigned(0,"No Description") CP0_SrsCtl_HSS = Param.Unsigned(0,"No Description") diff --git a/src/arch/mips/MipsSystem.py b/src/arch/mips/MipsSystem.py index c3dcf4e0b4..d271bd3872 100644 --- a/src/arch/mips/MipsSystem.py +++ b/src/arch/mips/MipsSystem.py @@ -28,10 +28,10 @@ # # Authors: Jaidev Patwardhan -from m5.SimObject import SimObject +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env + from System import System class MipsSystem(System): @@ -42,7 +42,7 @@ class MipsSystem(System): system_type = Param.UInt64("Type of system we are emulating") system_rev = Param.UInt64("Revision of system we are emulating") -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: class LinuxMipsSystem(MipsSystem): type = 'LinuxMipsSystem' system_type = 34 diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py index 15b03fd33d..9f7dc43b3f 100644 --- a/src/arch/x86/X86TLB.py +++ b/src/arch/x86/X86TLB.py @@ -53,13 +53,14 @@ # # Authors: Gabe Black -from MemObject import MemObject +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env -from BaseTLB import BaseTLB -if build_env['FULL_SYSTEM']: +from BaseTLB import BaseTLB +from MemObject import MemObject + +if buildEnv['FULL_SYSTEM']: class X86PagetableWalker(MemObject): type = 'X86PagetableWalker' cxx_class = 'X86ISA::Walker' @@ -70,6 +71,6 @@ class X86TLB(BaseTLB): type = 'X86TLB' cxx_class = 'X86ISA::TLB' size = Param.Int(64, "TLB size") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: walker = Param.X86PagetableWalker(\ X86PagetableWalker(), "page table walker") diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 4661375ba4..75114053e7 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -26,36 +26,38 @@ # # Authors: Nathan Binkert -from MemObject import MemObject +import sys + +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env + from Bus import Bus from InstTracer import InstTracer from ExeTracer import ExeTracer -import sys +from MemObject import MemObject default_tracer = ExeTracer() -if build_env['TARGET_ISA'] == 'alpha': +if buildEnv['TARGET_ISA'] == 'alpha': from AlphaTLB import AlphaDTB, AlphaITB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from AlphaInterrupts import AlphaInterrupts -elif build_env['TARGET_ISA'] == 'sparc': +elif buildEnv['TARGET_ISA'] == 'sparc': from SparcTLB import SparcTLB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from SparcInterrupts import SparcInterrupts -elif build_env['TARGET_ISA'] == 'x86': +elif buildEnv['TARGET_ISA'] == 'x86': from X86TLB import X86TLB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from X86LocalApic import X86LocalApic -elif build_env['TARGET_ISA'] == 'mips': +elif buildEnv['TARGET_ISA'] == 'mips': from MipsTLB import MipsTLB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from MipsInterrupts import MipsInterrupts -elif build_env['TARGET_ISA'] == 'arm': +elif buildEnv['TARGET_ISA'] == 'arm': from ArmTLB import ArmTLB - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: from ArmInterrupts import ArmInterrupts class BaseCPU(MemObject): @@ -76,47 +78,47 @@ class BaseCPU(MemObject): do_statistics_insts = Param.Bool(True, "enable statistics pseudo instructions") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: profile = Param.Latency('0ns', "trace the kernel stack") do_quiesce = Param.Bool(True, "enable quiesce instructions") else: workload = VectorParam.Process("processes to run") - if build_env['TARGET_ISA'] == 'sparc': + if buildEnv['TARGET_ISA'] == 'sparc': dtb = Param.SparcTLB(SparcTLB(), "Data TLB") itb = Param.SparcTLB(SparcTLB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: interrupts = Param.SparcInterrupts( SparcInterrupts(), "Interrupt Controller") - elif build_env['TARGET_ISA'] == 'alpha': + elif buildEnv['TARGET_ISA'] == 'alpha': dtb = Param.AlphaTLB(AlphaDTB(), "Data TLB") itb = Param.AlphaTLB(AlphaITB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: interrupts = Param.AlphaInterrupts( AlphaInterrupts(), "Interrupt Controller") - elif build_env['TARGET_ISA'] == 'x86': + elif buildEnv['TARGET_ISA'] == 'x86': dtb = Param.X86TLB(X86TLB(), "Data TLB") itb = Param.X86TLB(X86TLB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: _localApic = X86LocalApic(pio_addr=0x2000000000000000) interrupts = \ Param.X86LocalApic(_localApic, "Interrupt Controller") - elif build_env['TARGET_ISA'] == 'mips': + elif buildEnv['TARGET_ISA'] == 'mips': dtb = Param.MipsTLB(MipsTLB(), "Data TLB") itb = Param.MipsTLB(MipsTLB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: interrupts = Param.MipsInterrupts( MipsInterrupts(), "Interrupt Controller") - elif build_env['TARGET_ISA'] == 'arm': + elif buildEnv['TARGET_ISA'] == 'arm': UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?") dtb = Param.ArmTLB(ArmTLB(), "Data TLB") itb = Param.ArmTLB(ArmTLB(), "Instruction TLB") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: interrupts = Param.ArmInterrupts( ArmInterrupts(), "Interrupt Controller") else: print "Don't know what TLB to use for ISA %s" % \ - build_env['TARGET_ISA'] + buildEnv['TARGET_ISA'] sys.exit(1) max_insts_all_threads = Param.Counter(0, @@ -139,7 +141,7 @@ class BaseCPU(MemObject): tracer = Param.InstTracer(default_tracer, "Instruction tracer") _mem_ports = [] - if build_env['TARGET_ISA'] == 'x86' and build_env['FULL_SYSTEM']: + if buildEnv['TARGET_ISA'] == 'x86' and buildEnv['FULL_SYSTEM']: _mem_ports = ["itb.walker.port", "dtb.walker.port", "interrupts.pio", @@ -157,7 +159,7 @@ class BaseCPU(MemObject): self.icache_port = ic.cpu_side self.dcache_port = dc.cpu_side self._mem_ports = ['icache.mem_side', 'dcache.mem_side'] - if build_env['TARGET_ISA'] == 'x86' and build_env['FULL_SYSTEM']: + if buildEnv['TARGET_ISA'] == 'x86' and buildEnv['FULL_SYSTEM']: self._mem_ports += ["itb.walker_port", "dtb.walker_port"] def addTwoLevelCacheHierarchy(self, ic, dc, l2c): @@ -168,7 +170,7 @@ class BaseCPU(MemObject): self.l2cache.cpu_side = self.toL2Bus.port self._mem_ports = ['l2cache.mem_side'] - if build_env['TARGET_ISA'] == 'mips': + if buildEnv['TARGET_ISA'] == 'mips': CP0_IntCtl_IPTI = Param.Unsigned(0,"No Description") CP0_IntCtl_IPPCI = Param.Unsigned(0,"No Description") CP0_SrsCtl_HSS = Param.Unsigned(0,"No Description") diff --git a/src/cpu/CheckerCPU.py b/src/cpu/CheckerCPU.py index bff9af62d2..132254413f 100644 --- a/src/cpu/CheckerCPU.py +++ b/src/cpu/CheckerCPU.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU class CheckerCPU(BaseCPU): diff --git a/src/cpu/inorder/InOrderCPU.py b/src/cpu/inorder/InOrderCPU.py index 9faadc68cb..a0b0466a70 100644 --- a/src/cpu/inorder/InOrderCPU.py +++ b/src/cpu/inorder/InOrderCPU.py @@ -28,7 +28,6 @@ from m5.params import * from m5.proxy import * -from m5 import build_env from BaseCPU import BaseCPU class InOrderCPU(BaseCPU): diff --git a/src/cpu/memtest/MemTest.py b/src/cpu/memtest/MemTest.py index 629fd4877f..8e1b3a8d09 100644 --- a/src/cpu/memtest/MemTest.py +++ b/src/cpu/memtest/MemTest.py @@ -29,7 +29,6 @@ from MemObject import MemObject from m5.params import * from m5.proxy import * -from m5 import build_env class MemTest(MemObject): type = 'MemTest' diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py index 56e537ad2f..3f2210e44c 100644 --- a/src/cpu/o3/O3CPU.py +++ b/src/cpu/o3/O3CPU.py @@ -26,21 +26,21 @@ # # Authors: Kevin Lim +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env from BaseCPU import BaseCPU from FUPool import * -if build_env['USE_CHECKER']: +if buildEnv['USE_CHECKER']: from O3Checker import O3Checker class DerivO3CPU(BaseCPU): type = 'DerivO3CPU' activity = Param.Unsigned(0, "Initial count") - if build_env['USE_CHECKER']: - if not build_env['FULL_SYSTEM']: + if buildEnv['USE_CHECKER']: + if not buildEnv['FULL_SYSTEM']: checker = Param.BaseCPU(O3Checker(workload=Parent.workload, exitOnError=False, updateOnError=True, diff --git a/src/cpu/o3/O3Checker.py b/src/cpu/o3/O3Checker.py index edc6dc9b6f..d0c4ce537e 100644 --- a/src/cpu/o3/O3Checker.py +++ b/src/cpu/o3/O3Checker.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU class O3Checker(BaseCPU): diff --git a/src/cpu/ozone/OzoneCPU.py b/src/cpu/ozone/OzoneCPU.py index 37386898d1..2c7b8475fd 100644 --- a/src/cpu/ozone/OzoneCPU.py +++ b/src/cpu/ozone/OzoneCPU.py @@ -26,11 +26,11 @@ # # Authors: Kevin Lim +from m5.defines import buildEnv from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU -if build_env['USE_CHECKER']: +if buildEnv['USE_CHECKER']: from OzoneChecker import OzoneChecker class DerivOzoneCPU(BaseCPU): @@ -38,7 +38,7 @@ class DerivOzoneCPU(BaseCPU): numThreads = Param.Unsigned("number of HW thread contexts") - if build_env['USE_CHECKER']: + if buildEnv['USE_CHECKER']: checker = Param.BaseCPU("Checker CPU") icache_port = Port("Instruction Port") diff --git a/src/cpu/ozone/OzoneChecker.py b/src/cpu/ozone/OzoneChecker.py index bfa39ead90..bbe46db18b 100644 --- a/src/cpu/ozone/OzoneChecker.py +++ b/src/cpu/ozone/OzoneChecker.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU class OzoneChecker(BaseCPU): diff --git a/src/cpu/ozone/SimpleOzoneCPU.py b/src/cpu/ozone/SimpleOzoneCPU.py index 93603092bf..d4620cd8e7 100644 --- a/src/cpu/ozone/SimpleOzoneCPU.py +++ b/src/cpu/ozone/SimpleOzoneCPU.py @@ -26,8 +26,8 @@ # # Authors: Kevin Lim +from m5.defines import buildEnv from m5.params import * -from m5 import build_env from BaseCPU import BaseCPU class SimpleOzoneCPU(BaseCPU): @@ -35,7 +35,7 @@ class SimpleOzoneCPU(BaseCPU): numThreads = Param.Unsigned("number of HW thread contexts") - if not build_env['FULL_SYSTEM']: + if not buildEnv['FULL_SYSTEM']: mem = Param.FunctionalMemory(NULL, "memory") width = Param.Unsigned("Width") diff --git a/src/cpu/simple/AtomicSimpleCPU.py b/src/cpu/simple/AtomicSimpleCPU.py index b7174bb439..3d72f4098f 100644 --- a/src/cpu/simple/AtomicSimpleCPU.py +++ b/src/cpu/simple/AtomicSimpleCPU.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseSimpleCPU import BaseSimpleCPU class AtomicSimpleCPU(BaseSimpleCPU): diff --git a/src/cpu/simple/TimingSimpleCPU.py b/src/cpu/simple/TimingSimpleCPU.py index ce68392411..6b83c41aaf 100644 --- a/src/cpu/simple/TimingSimpleCPU.py +++ b/src/cpu/simple/TimingSimpleCPU.py @@ -27,7 +27,6 @@ # Authors: Nathan Binkert from m5.params import * -from m5 import build_env from BaseSimpleCPU import BaseSimpleCPU class TimingSimpleCPU(BaseSimpleCPU): diff --git a/src/dev/Uart.py b/src/dev/Uart.py index 5135a064d8..9254dc695e 100644 --- a/src/dev/Uart.py +++ b/src/dev/Uart.py @@ -28,7 +28,6 @@ from m5.params import * from m5.proxy import * -from m5 import build_env from Device import BasicPioDevice class Uart(BasicPioDevice): diff --git a/src/mem/Bus.py b/src/mem/Bus.py index 0f113cc09d..b3f6b29463 100644 --- a/src/mem/Bus.py +++ b/src/mem/Bus.py @@ -26,12 +26,12 @@ # # Authors: Nathan Binkert -from m5 import build_env +from m5.defines import buildEnv from m5.params import * from m5.proxy import * from MemObject import MemObject -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: from Device import BadAddr class Bus(MemObject): diff --git a/src/python/SConscript b/src/python/SConscript index bb892f3765..935986a12f 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -38,7 +38,6 @@ PySource('', 'importer.py') PySource('m5', 'm5/__init__.py') PySource('m5', 'm5/SimObject.py') PySource('m5', 'm5/config.py') -PySource('m5', 'm5/convert.py') PySource('m5', 'm5/core.py') PySource('m5', 'm5/debug.py') PySource('m5', 'm5/event.py') @@ -47,18 +46,18 @@ PySource('m5', 'm5/options.py') PySource('m5', 'm5/params.py') PySource('m5', 'm5/proxy.py') PySource('m5', 'm5/simulate.py') -PySource('m5', 'm5/smartdict.py') PySource('m5', 'm5/stats.py') PySource('m5', 'm5/ticks.py') PySource('m5', 'm5/trace.py') PySource('m5.util', 'm5/util/__init__.py') PySource('m5.util', 'm5/util/attrdict.py') PySource('m5.util', 'm5/util/code_formatter.py') +PySource('m5.util', 'm5/util/convert.py') PySource('m5.util', 'm5/util/grammar.py') PySource('m5.util', 'm5/util/jobfile.py') -PySource('m5.util', 'm5/util/misc.py') PySource('m5.util', 'm5/util/multidict.py') PySource('m5.util', 'm5/util/orderdict.py') +PySource('m5.util', 'm5/util/smartdict.py') SwigSource('m5.internal', 'swig/core.i') SwigSource('m5.internal', 'swig/debug.i') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 8ef22be4e3..0e0ffaea98 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -31,47 +31,24 @@ import math import sys import types -import proxy +try: + import pydot +except: + pydot = False + import m5 -from util import * - -# These utility functions have to come first because they're -# referenced in params.py... otherwise they won't be defined when we -# import params below, and the recursive import of this file from -# params.py will not find these names. -def isSimObject(value): - return isinstance(value, SimObject) - -def isSimObjectClass(value): - return issubclass(value, SimObject) - -def isSimObjectSequence(value): - if not isinstance(value, (list, tuple)) or len(value) == 0: - return False - - for val in value: - if not isNullPointer(val) and not isSimObject(val): - return False - - return True - -def isSimObjectOrSequence(value): - return isSimObject(value) or isSimObjectSequence(value) +from m5.util import * # Have to import params up top since Param is referenced on initial # load (when SimObject class references Param to create a class # variable, the 'name' param)... -from params import * +from m5.params import * # There are a few things we need that aren't in params.__all__ since # normal users don't need them -from params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector -from proxy import * +from m5.params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector -noDot = False -try: - import pydot -except: - noDot = True +from m5.proxy import * +from m5.proxy import isproxy ##################################################################### # @@ -141,7 +118,7 @@ class MetaSimObject(type): # and only allow "private" attributes to be passed to the base # __new__ (starting with underscore). def __new__(mcls, name, bases, dict): - assert name not in allClasses + assert name not in allClasses, "SimObject %s already present" % name # Copy "private" attributes, functions, and classes to the # official dict. Everything else goes in _init_dict to be @@ -678,7 +655,7 @@ class SimObject(object): def unproxy_all(self): for param in self._params.iterkeys(): value = self._values.get(param) - if value != None and proxy.isproxy(value): + if value != None and isproxy(value): try: value = value.unproxy(self) except: @@ -749,8 +726,8 @@ class SimObject(object): for param in param_names: value = self._values.get(param) if value is None: - m5.fatal("%s.%s without default or user set value", - self.path(), param) + fatal("%s.%s without default or user set value", + self.path(), param) value = value.getValue() if isinstance(self._params[param], VectorParamDesc): @@ -886,6 +863,34 @@ def resolveSimObject(name): obj = instanceDict[name] return obj.getCCObject() +def isSimObject(value): + return isinstance(value, SimObject) + +def isSimObjectClass(value): + return issubclass(value, SimObject) + +def isSimObjectSequence(value): + if not isinstance(value, (list, tuple)) or len(value) == 0: + return False + + for val in value: + if not isNullPointer(val) and not isSimObject(val): + return False + + return True + +def isSimObjectOrSequence(value): + return isSimObject(value) or isSimObjectSequence(value) + +baseClasses = allClasses.copy() +baseInstances = instanceDict.copy() + +def clear(): + global allClasses, instanceDict + + allClasses = baseClasses.copy() + instanceDict = baseInstances.copy() + # __all__ defines the list of symbols that get exported when # 'from config import *' is invoked. Try to keep this reasonably # short to avoid polluting other namespaces. diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index c3512cd0dd..9f9459ae8b 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -25,106 +25,24 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Nathan Binkert -# Steve Reinhardt -import os -import sys +# Import useful subpackages of M5, but *only* when run as an m5 +# script. This is mostly to keep backward compatibility with existing +# scripts while allowing new SCons code to operate properly. -import smartdict - -# define a MaxTick parameter -MaxTick = 2**63 - 1 - -# define this here so we can use it right away if necessary - -def errorURL(prefix, s): - try: - import zlib - hashstr = "%x" % zlib.crc32(s) - except: - hashstr = "UnableToHash" - return "For more information see: http://www.m5sim.org/%s/%s" % \ - (prefix, hashstr) - - -# panic() should be called when something happens that should never -# ever happen regardless of what the user does (i.e., an acutal m5 -# bug). -def panic(fmt, *args): - print >>sys.stderr, 'panic:', fmt % args - print >>sys.stderr, errorURL('panic',fmt) - sys.exit(1) - -# fatal() should be called when the simulation cannot continue due to -# some condition that is the user's fault (bad configuration, invalid -# arguments, etc.) and not a simulator bug. -def fatal(fmt, *args): - print >>sys.stderr, 'fatal:', fmt % args - print >>sys.stderr, errorURL('fatal',fmt) - sys.exit(1) - -# force scalars to one-element lists for uniformity -def makeList(objOrList): - if isinstance(objOrList, list): - return objOrList - return [objOrList] - -# Prepend given directory to system module search path. We may not -# need this anymore if we can structure our config library more like a -# Python package. -def AddToPath(path): - # if it's a relative path and we know what directory the current - # python script is in, make the path relative to that directory. - if not os.path.isabs(path) and sys.path[0]: - path = os.path.join(sys.path[0], path) - path = os.path.realpath(path) - # sys.path[0] should always refer to the current script's directory, - # so place the new dir right after that. - sys.path.insert(1, path) - -# make a SmartDict out of the build options for our local use -build_env = smartdict.SmartDict() - -# make a SmartDict out of the OS environment too -env = smartdict.SmartDict() -env.update(os.environ) - -# Since we have so many mutual imports in this package, we should: -# 1. Put all intra-package imports at the *bottom* of the file, unless -# they're absolutely needed before that (for top-level statements -# or class attributes). Imports of "trivial" packages that don't -# import other packages (e.g., 'smartdict') can be at the top. -# 2. Never use 'from foo import *' on an intra-package import since -# you can get the wrong result if foo is only partially imported -# at the point you do that (i.e., because foo is in the middle of -# importing *you*). try: import internal except ImportError: internal = None -try: - import defines - build_env.update(defines.buildEnv) -except ImportError: - defines = None - if internal: - defines.compileDate = internal.core.compileDate - for k,v in internal.core.__dict__.iteritems(): - if k.startswith('flag_'): - setattr(defines, k[5:], v) + import SimObject + import core + import objects + import params + import stats + import util from event import * - from simulate import * from main import options, main - import stats - import core - -import SimObject -import params - -try: - import objects -except ImportError: - objects = None + from simulate import * diff --git a/src/python/m5/environment.py b/src/python/m5/environment.py deleted file mode 100644 index bea0bc1d07..0000000000 --- a/src/python/m5/environment.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2005 The Regents of The University of Michigan -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Nathan Binkert -# Steve Reinhardt - -import os - -# import the m5 compile options -import defines - -# make a SmartDict out of the build options for our local use -import smartdict -build_env = smartdict.SmartDict() -build_env.update(defines.m5_build_env) - -# make a SmartDict out of the OS environment too -env = smartdict.SmartDict() -env.update(os.environ) - diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 2a308ff09f..29f8cc9764 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -32,7 +32,7 @@ import os import socket import sys -from util import attrdict +from util import attrdict, fatal import config from options import OptionParser diff --git a/src/python/m5/params.py b/src/python/m5/params.py index edd78fa288..3a3a300148 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -50,13 +50,10 @@ import re import sys import time -import convert import proxy import ticks from util import * -import SimObject - def isSimObject(*args, **kwargs): return SimObject.isSimObject(*args, **kwargs) @@ -711,32 +708,31 @@ class MetaEnum(MetaParamValue): super(MetaEnum, cls).__init__(name, bases, init_dict) - def __str__(cls): - return cls.__name__ - # Generate C++ class declaration for this enum type. # Note that we wrap the enum in a class/struct to act as a namespace, # so that the enum strings can be brief w/o worrying about collisions. def cxx_decl(cls): - code = "#ifndef __ENUM__%s\n" % cls - code += '#define __ENUM__%s\n' % cls + name = cls.__name__ + code = "#ifndef __ENUM__%s\n" % name + code += '#define __ENUM__%s\n' % name code += '\n' code += 'namespace Enums {\n' - code += ' enum %s {\n' % cls + code += ' enum %s {\n' % name for val in cls.vals: code += ' %s = %d,\n' % (val, cls.map[val]) - code += ' Num_%s = %d,\n' % (cls, len(cls.vals)) + code += ' Num_%s = %d,\n' % (name, len(cls.vals)) code += ' };\n' - code += ' extern const char *%sStrings[Num_%s];\n' % (cls, cls) + code += ' extern const char *%sStrings[Num_%s];\n' % (name, name) code += '}\n' code += '\n' code += '#endif\n' return code def cxx_def(cls): - code = '#include "enums/%s.hh"\n' % cls + name = cls.__name__ + code = '#include "enums/%s.hh"\n' % name code += 'namespace Enums {\n' - code += ' const char *%sStrings[Num_%s] =\n' % (cls, cls) + code += ' const char *%sStrings[Num_%s] =\n' % (name, name) code += ' {\n' for val in cls.vals: code += ' "%s",\n' % val @@ -1170,6 +1166,15 @@ class PortParamDesc(object): ptype_str = 'Port' ptype = Port +baseEnums = allEnums.copy() +baseParams = allParams.copy() + +def clear(): + global allEnums, allParams + + allEnums = baseEnums.copy() + allParams = baseParams.copy() + __all__ = ['Param', 'VectorParam', 'Enum', 'Bool', 'String', 'Float', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', @@ -1184,3 +1189,5 @@ __all__ = ['Param', 'VectorParam', 'Time', 'NextEthernetAddr', 'NULL', 'Port', 'VectorPort'] + +import SimObject diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py index 45992fe85e..092bd03395 100644 --- a/src/python/m5/simulate.py +++ b/src/python/m5/simulate.py @@ -40,6 +40,9 @@ import SimObject import ticks import objects +# define a MaxTick parameter +MaxTick = 2**63 - 1 + # The final hook to generate .ini files. Called from the user script # once the config is built. def instantiate(root): diff --git a/src/python/m5/ticks.py b/src/python/m5/ticks.py index 91834c9c88..181a65eba6 100644 --- a/src/python/m5/ticks.py +++ b/src/python/m5/ticks.py @@ -41,7 +41,7 @@ def fixGlobalFrequency(): print "Global frequency set at %d ticks per second" % int(tps) def setGlobalFrequency(ticksPerSecond): - import convert + from m5.util import convert global tps, tps_fixed diff --git a/src/python/m5/trace.py b/src/python/m5/trace.py index 17aa6196c8..db239040ab 100644 --- a/src/python/m5/trace.py +++ b/src/python/m5/trace.py @@ -48,5 +48,5 @@ def help(): if flag == 'All': continue print " %s: %s" % (flag, flags.descriptions[flag]) - util.print_list(flags.compoundMap[flag], indent=8) + util.printList(flags.compoundMap[flag], indent=8) print diff --git a/src/python/m5/util/__init__.py b/src/python/m5/util/__init__.py index 3930c8b6f4..7a674dd2dd 100644 --- a/src/python/m5/util/__init__.py +++ b/src/python/m5/util/__init__.py @@ -1,4 +1,5 @@ -# Copyright (c) 2008 The Hewlett-Packard Development Company +# Copyright (c) 2008-2009 The Hewlett-Packard Development Company +# Copyright (c) 2004-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -26,14 +27,130 @@ # # Authors: Nathan Binkert -from attrdict import attrdict, optiondict -from code_formatter import code_formatter -from misc import * -from multidict import multidict -from orderdict import orderdict +import os +import re +import sys + +import convert import jobfile -def print_list(items, indent=4): +from attrdict import attrdict, optiondict +from code_formatter import code_formatter +from multidict import multidict +from orderdict import orderdict +from smartdict import SmartDict + +# define this here so we can use it right away if necessary +def errorURL(prefix, s): + try: + import zlib + hashstr = "%x" % zlib.crc32(s) + except: + hashstr = "UnableToHash" + return "For more information see: http://www.m5sim.org/%s/%s" % \ + (prefix, hashstr) + +# panic() should be called when something happens that should never +# ever happen regardless of what the user does (i.e., an acutal m5 +# bug). +def panic(fmt, *args): + print >>sys.stderr, 'panic:', fmt % args + print >>sys.stderr, errorURL('panic',fmt) + sys.exit(1) + +# fatal() should be called when the simulation cannot continue due to +# some condition that is the user's fault (bad configuration, invalid +# arguments, etc.) and not a simulator bug. +def fatal(fmt, *args): + print >>sys.stderr, 'fatal:', fmt % args + print >>sys.stderr, errorURL('fatal',fmt) + sys.exit(1) + +class Singleton(type): + def __call__(cls, *args, **kwargs): + if hasattr(cls, '_instance'): + return cls._instance + + cls._instance = super(Singleton, cls).__call__(*args, **kwargs) + return cls._instance + +def addToPath(path): + """Prepend given directory to system module search path. We may not + need this anymore if we can structure our config library more like a + Python package.""" + + # if it's a relative path and we know what directory the current + # python script is in, make the path relative to that directory. + if not os.path.isabs(path) and sys.path[0]: + path = os.path.join(sys.path[0], path) + path = os.path.realpath(path) + # sys.path[0] should always refer to the current script's directory, + # so place the new dir right after that. + sys.path.insert(1, path) + +# Apply method to object. +# applyMethod(obj, 'meth', ) is equivalent to obj.meth() +def applyMethod(obj, meth, *args, **kwargs): + return getattr(obj, meth)(*args, **kwargs) + +# If the first argument is an (non-sequence) object, apply the named +# method with the given arguments. If the first argument is a +# sequence, apply the method to each element of the sequence (a la +# 'map'). +def applyOrMap(objOrSeq, meth, *args, **kwargs): + if not isinstance(objOrSeq, (list, tuple)): + return applyMethod(objOrSeq, meth, *args, **kwargs) + else: + return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] + +def compareVersions(v1, v2): + """helper function: compare arrays or strings of version numbers. + E.g., compare_version((1,3,25), (1,4,1)') + returns -1, 0, 1 if v1 is <, ==, > v2 + """ + def make_version_list(v): + if isinstance(v, (list,tuple)): + return v + elif isinstance(v, str): + return map(lambda x: int(re.match('\d+', x).group()), v.split('.')) + else: + raise TypeError + + v1 = make_version_list(v1) + v2 = make_version_list(v2) + # Compare corresponding elements of lists + for n1,n2 in zip(v1, v2): + if n1 < n2: return -1 + if n1 > n2: return 1 + # all corresponding values are equal... see if one has extra values + if len(v1) < len(v2): return -1 + if len(v1) > len(v2): return 1 + return 0 + +def crossproduct(items): + if len(items) == 1: + for i in items[0]: + yield (i,) + else: + for i in items[0]: + for j in crossproduct(items[1:]): + yield (i,) + j + +def flatten(items): + while items: + item = items.pop(0) + if isinstance(item, (list, tuple)): + items[0:0] = item + else: + yield item + +# force scalars to one-element lists for uniformity +def makeList(objOrList): + if isinstance(objOrList, list): + return objOrList + return [objOrList] + +def printList(items, indent=4): line = ' ' * indent for i,item in enumerate(items): if len(line) + len(item) > 76: @@ -45,3 +162,27 @@ def print_list(items, indent=4): else: line += item print line + +def readCommand(cmd, **kwargs): + """run the command cmd, read the results and return them + this is sorta like `cmd` in shell""" + from subprocess import Popen, PIPE, STDOUT + + if isinstance(cmd, str): + cmd = cmd.split() + + no_exception = 'exception' in kwargs + exception = kwargs.pop('exception', None) + + kwargs.setdefault('shell', False) + kwargs.setdefault('stdout', PIPE) + kwargs.setdefault('stderr', STDOUT) + kwargs.setdefault('close_fds', True) + try: + subp = Popen(cmd, **kwargs) + except Exception, e: + if no_exception: + return exception + raise + + return subp.communicate()[0] diff --git a/src/python/m5/convert.py b/src/python/m5/util/convert.py similarity index 100% rename from src/python/m5/convert.py rename to src/python/m5/util/convert.py diff --git a/src/python/m5/util/jobfile.py b/src/python/m5/util/jobfile.py index c830895f67..9c59778e54 100644 --- a/src/python/m5/util/jobfile.py +++ b/src/python/m5/util/jobfile.py @@ -28,9 +28,6 @@ import sys -from attrdict import optiondict -from misc import crossproduct - class Data(object): def __init__(self, name, desc, **kwargs): self.name = name @@ -108,7 +105,8 @@ class Data(object): yield key def optiondict(self): - result = optiondict() + import m5.util + result = m5.util.optiondict() for key in self: result[key] = self[key] return result @@ -328,7 +326,9 @@ class Configuration(Data): optgroups = [ g.subopts() for g in groups ] if not optgroups: return - for options in crossproduct(optgroups): + + import m5.util + for options in m5.util.crossproduct(optgroups): for opt in options: cpt = opt._group._checkpoint if not isinstance(cpt, bool) and cpt != opt: diff --git a/src/python/m5/util/misc.py b/src/python/m5/util/misc.py deleted file mode 100644 index 094e3ed9a1..0000000000 --- a/src/python/m5/util/misc.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (c) 2004-2006 The Regents of The University of Michigan -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Steve Reinhardt -# Nathan Binkert - -############################# -# -# Utility classes & methods -# -############################# - -class Singleton(type): - def __call__(cls, *args, **kwargs): - if hasattr(cls, '_instance'): - return cls._instance - - cls._instance = super(Singleton, cls).__call__(*args, **kwargs) - return cls._instance - -# Apply method to object. -# applyMethod(obj, 'meth', ) is equivalent to obj.meth() -def applyMethod(obj, meth, *args, **kwargs): - return getattr(obj, meth)(*args, **kwargs) - -# If the first argument is an (non-sequence) object, apply the named -# method with the given arguments. If the first argument is a -# sequence, apply the method to each element of the sequence (a la -# 'map'). -def applyOrMap(objOrSeq, meth, *args, **kwargs): - if not isinstance(objOrSeq, (list, tuple)): - return applyMethod(objOrSeq, meth, *args, **kwargs) - else: - return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] - -def crossproduct(items): - if not isinstance(items, (list, tuple)): - raise AttributeError, 'crossproduct works only on sequences' - - if not items: - yield None - return - - current = items[0] - remainder = items[1:] - - if not hasattr(current, '__iter__'): - current = [ current ] - - for item in current: - for rem in crossproduct(remainder): - data = [ item ] - if rem: - data += rem - yield data - -def flatten(items): - if not isinstance(items, (list, tuple)): - yield items - return - - for item in items: - for flat in flatten(item): - yield flat diff --git a/src/python/m5/smartdict.py b/src/python/m5/util/smartdict.py similarity index 100% rename from src/python/m5/smartdict.py rename to src/python/m5/util/smartdict.py diff --git a/src/sim/System.py b/src/sim/System.py index 3b0bc1e462..06a54a78db 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -27,9 +27,10 @@ # Authors: Nathan Binkert from m5.SimObject import SimObject +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env + from PhysicalMemory import * class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing'] @@ -40,7 +41,7 @@ class System(SimObject): physmem = Param.PhysicalMemory(Parent.any, "physical memory") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: abstract = True boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency, "boot processor frequency") diff --git a/tests/configs/inorder-timing.py b/tests/configs/inorder-timing.py index 62f8b58504..10f9e42321 100644 --- a/tests/configs/inorder-timing.py +++ b/tests/configs/inorder-timing.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') class MyCache(BaseCache): assoc = 2 diff --git a/tests/configs/o3-timing-mp-ruby.py b/tests/configs/o3-timing-mp-ruby.py index eab9bfaf23..77e1ba9924 100644 --- a/tests/configs/o3-timing-mp-ruby.py +++ b/tests/configs/o3-timing-mp-ruby.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') nb_cores = 4 cpus = [ DerivO3CPU(cpu_id=i) for i in xrange(nb_cores) ] diff --git a/tests/configs/o3-timing-mp.py b/tests/configs/o3-timing-mp.py index fc6a72a824..59776d5c3e 100644 --- a/tests/configs/o3-timing-mp.py +++ b/tests/configs/o3-timing-mp.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') # -------------------- # Base L1 Cache diff --git a/tests/configs/o3-timing-ruby.py b/tests/configs/o3-timing-ruby.py index a91a9cf398..f7ad41d99c 100644 --- a/tests/configs/o3-timing-ruby.py +++ b/tests/configs/o3-timing-ruby.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import ruby_config diff --git a/tests/configs/o3-timing.py b/tests/configs/o3-timing.py index 366a3eb0d4..563772213f 100644 --- a/tests/configs/o3-timing.py +++ b/tests/configs/o3-timing.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') class MyCache(BaseCache): assoc = 2 diff --git a/tests/configs/t1000-simple-atomic.py b/tests/configs/t1000-simple-atomic.py index 6a078e7152..35b329f578 100644 --- a/tests/configs/t1000-simple-atomic.py +++ b/tests/configs/t1000-simple-atomic.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig cpu = AtomicSimpleCPU(cpu_id=0) diff --git a/tests/configs/tsunami-o3-dual.py b/tests/configs/tsunami-o3-dual.py index 3044f54335..76aca38062 100644 --- a/tests/configs/tsunami-o3-dual.py +++ b/tests/configs/tsunami-o3-dual.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig diff --git a/tests/configs/tsunami-o3.py b/tests/configs/tsunami-o3.py index 34fa235bd6..9b52cd92be 100644 --- a/tests/configs/tsunami-o3.py +++ b/tests/configs/tsunami-o3.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig diff --git a/tests/configs/tsunami-simple-atomic-dual.py b/tests/configs/tsunami-simple-atomic-dual.py index 593b026801..dfbdd101df 100644 --- a/tests/configs/tsunami-simple-atomic-dual.py +++ b/tests/configs/tsunami-simple-atomic-dual.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig # -------------------- diff --git a/tests/configs/tsunami-simple-atomic.py b/tests/configs/tsunami-simple-atomic.py index 0c6feaeace..cfc619b061 100644 --- a/tests/configs/tsunami-simple-atomic.py +++ b/tests/configs/tsunami-simple-atomic.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig # -------------------- diff --git a/tests/configs/tsunami-simple-timing-dual.py b/tests/configs/tsunami-simple-timing-dual.py index 2124499141..ce17475e34 100644 --- a/tests/configs/tsunami-simple-timing-dual.py +++ b/tests/configs/tsunami-simple-timing-dual.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig # -------------------- diff --git a/tests/configs/tsunami-simple-timing.py b/tests/configs/tsunami-simple-timing.py index f0eaa08d7d..0c39846288 100644 --- a/tests/configs/tsunami-simple-timing.py +++ b/tests/configs/tsunami-simple-timing.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') import FSConfig diff --git a/tests/configs/twosys-tsunami-simple-atomic.py b/tests/configs/twosys-tsunami-simple-atomic.py index e7214a0598..ce191930ea 100644 --- a/tests/configs/twosys-tsunami-simple-atomic.py +++ b/tests/configs/twosys-tsunami-simple-atomic.py @@ -28,7 +28,7 @@ import m5 from m5.objects import * -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from FSConfig import * from Benchmarks import * diff --git a/tests/long/00.gzip/test.py b/tests/long/00.gzip/test.py index f69914046e..7acce6e81a 100644 --- a/tests/long/00.gzip/test.py +++ b/tests/long/00.gzip/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import gzip_log workload = gzip_log(isa, opsys, 'smred') diff --git a/tests/long/10.mcf/test.py b/tests/long/10.mcf/test.py index c4ffb248ad..9bd18a83fc 100644 --- a/tests/long/10.mcf/test.py +++ b/tests/long/10.mcf/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import mcf workload = mcf(isa, opsys, 'smred') diff --git a/tests/long/20.parser/test.py b/tests/long/20.parser/test.py index 8e745ec262..c96a46e60d 100644 --- a/tests/long/20.parser/test.py +++ b/tests/long/20.parser/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import parser workload = parser(isa, opsys, 'mdred') diff --git a/tests/long/30.eon/test.py b/tests/long/30.eon/test.py index 318da1049f..de4d12dd84 100644 --- a/tests/long/30.eon/test.py +++ b/tests/long/30.eon/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import eon_cook workload = eon_cook(isa, opsys, 'mdred') diff --git a/tests/long/40.perlbmk/test.py b/tests/long/40.perlbmk/test.py index e324162654..8fe5d60473 100644 --- a/tests/long/40.perlbmk/test.py +++ b/tests/long/40.perlbmk/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import perlbmk_makerand workload = perlbmk_makerand(isa, opsys, 'lgred') diff --git a/tests/long/50.vortex/test.py b/tests/long/50.vortex/test.py index fbf0dc0819..92422c234e 100644 --- a/tests/long/50.vortex/test.py +++ b/tests/long/50.vortex/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import vortex workload = vortex(isa, opsys, 'smred') diff --git a/tests/long/60.bzip2/test.py b/tests/long/60.bzip2/test.py index 7fa3d1a078..fa74d08602 100644 --- a/tests/long/60.bzip2/test.py +++ b/tests/long/60.bzip2/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import bzip2_source workload = bzip2_source(isa, opsys, 'lgred') diff --git a/tests/long/70.twolf/test.py b/tests/long/70.twolf/test.py index 85b106eb4e..761ec8b2e6 100644 --- a/tests/long/70.twolf/test.py +++ b/tests/long/70.twolf/test.py @@ -26,7 +26,7 @@ # # Authors: Korey Sewell -m5.AddToPath('../configs/common') +m5.util.addToPath('../configs/common') from cpu2000 import twolf import os From e9288b2cd35863c600d7ff7bf04f4c08e055e3e0 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: [PATCH 020/160] scons: add slicc and ply to sys.path and PYTHONPATH so everyone has access --- SConstruct | 19 ++++++++++++------- src/arch/isa_parser.py | 5 ----- src/arch/micro_asm.py | 4 ---- src/mem/protocol/SConscript | 1 - 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/SConstruct b/SConstruct index e34d60ec85..f143bca0e7 100644 --- a/SConstruct +++ b/SConstruct @@ -111,8 +111,12 @@ from os.path import join as joinpath, split as splitpath import SCons import SCons.Node -# M5 includes -sys.path[1:1] = [ Dir('src/python').srcnode().abspath ] +extra_python_paths = [ + Dir('src/python').srcnode().abspath, # M5 includes + Dir('ext/ply').srcnode().abspath, # ply is used by several files + ] + +sys.path[1:1] = extra_python_paths from m5.util import compareVersions, readCommand @@ -122,7 +126,7 @@ from m5.util import compareVersions, readCommand # ######################################################################## use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 'PATH', - 'RANLIB' ]) + 'PYTHONPATH', 'RANLIB' ]) use_env = {} for key,val in os.environ.iteritems(): @@ -133,6 +137,10 @@ main = Environment(ENV=use_env) main.root = Dir(".") # The current directory (where this file lives). main.srcdir = Dir("src") # The source directory +# add useful python code PYTHONPATH so it can be used by subprocesses +# as well +main.AppendENVPath('PYTHONPATH', extra_python_paths) + ######################################################################## # # Mercurial Stuff. @@ -338,9 +346,6 @@ Export('extras_dir_list') # the ext directory should be on the #includes path main.Append(CPPPATH=[Dir('ext')]) -# M5_PLY is used by isa_parser.py to find the PLY package. -main.Append(ENV = { 'M5_PLY' : Dir('ext/ply').abspath }) - CXX_version = readCommand([main['CXX'],'--version'], exception=False) CXX_V = readCommand([main['CXX'],'-V'], exception=False) @@ -386,7 +391,7 @@ if main['BATCH']: if sys.platform == 'cygwin': # cygwin has some header file issues... - main.Append(CCFLAGS=Split("-Wno-uninitialized")) + main.Append(CCFLAGS="-Wno-uninitialized") # Check for SWIG if not main.has_key('SWIG'): diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index d5b5bbe4f9..23260ca481 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -34,11 +34,6 @@ import traceback # get type names from types import * -# Prepend the directory where the PLY lex & yacc modules are found -# to the search path. Assumes we're compiling in a subdirectory -# of 'build' in the current tree. -sys.path[0:0] = [os.environ['M5_PLY']] - from ply import lex from ply import yacc diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py index 3433a80763..4e5400ceff 100644 --- a/src/arch/micro_asm.py +++ b/src/arch/micro_asm.py @@ -34,10 +34,6 @@ import traceback # get type names from types import * -# Prepend the directory where the PLY lex & yacc modules are found -# to the search path. -sys.path[0:0] = [os.environ['M5_PLY']] - from ply import lex from ply import yacc diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript index 293346f13b..700ab40ea6 100644 --- a/src/mem/protocol/SConscript +++ b/src/mem/protocol/SConscript @@ -73,7 +73,6 @@ protocol = env['PROTOCOL'] sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"), protocol_dir.File("%s.slicc" % protocol) ] -sys.path[0:0] = [env['ENV']['M5_PLY']] execfile(slicc_dir.File('parser/parser.py').srcnode().abspath) sm_files = read_slicc([s.srcnode().abspath for s in sources]) From 30d5d95b6a7c93ccf63ae0cfcc62d17306c31eee Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: [PATCH 021/160] params: small cleanup to param description internals --- src/SConscript | 7 +------ src/python/m5/params.py | 6 +++++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/SConscript b/src/SConscript index 687709ac13..d3323f0a09 100644 --- a/src/SConscript +++ b/src/SConscript @@ -489,12 +489,7 @@ for name,simobj in sorted(sim_objects.iteritems()): # Generate any parameter header files needed params_i_files = [] for name,param in all_params.iteritems(): - if isinstance(param, m5.params.VectorParamDesc): - ext = 'vptype' - else: - ext = 'ptype' - - i_file = File('params/%s_%s.i' % (name, ext)) + i_file = File('params/%s_%s.i' % (name, param.file_ext)) params_i_files.append(i_file) env.Command(i_file, Value(name), createSwigParam) env.Depends(i_file, depends) diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 3a3a300148..cf64070c55 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -93,6 +93,8 @@ class ParamValue(object): # Regular parameter description. class ParamDesc(object): + file_ext = 'ptype' + def __init__(self, ptype_str, ptype, *args, **kwargs): self.ptype_str = ptype_str # remember ptype only if it is provided @@ -127,7 +129,7 @@ class ParamDesc(object): def __getattr__(self, attr): if attr == 'ptype': ptype = SimObject.allClasses[self.ptype_str] - assert issubclass(ptype, SimObject.SimObject) + assert isSimObjectClass(ptype) self.ptype = ptype return ptype @@ -182,6 +184,8 @@ class SimObjVector(VectorParamValue): v.print_ini(ini_file) class VectorParamDesc(ParamDesc): + file_ext = 'vptype' + # Convert assigned value to appropriate type. If the RHS is not a # list or tuple, it generates a single-element list. def convert(self, value): From 2278363015a2a5cc850b38213833096d33b496e8 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 18:12:39 -0700 Subject: [PATCH 022/160] slicc: Pure python implementation of slicc. This is simply a translation of the C++ slicc into python with very minimal reorganization of the code. The output can be verified as nearly identical by doing a "diff -wBur". Slicc can easily be run manually by using util/slicc --- src/mem/protocol/SConscript | 84 +- src/mem/slicc/SConscript | 129 -- src/mem/slicc/__init__.py | 25 + src/mem/slicc/ast/AST.cc | 39 - src/mem/slicc/ast/AST.hh | 94 - src/mem/slicc/ast/AST.py | 63 + src/mem/slicc/ast/ASTs.hh | 91 - src/mem/slicc/ast/ActionDeclAST.cc | 98 - src/mem/slicc/ast/ActionDeclAST.hh | 86 - src/mem/slicc/ast/ActionDeclAST.py | 72 + src/mem/slicc/ast/AssignStatementAST.cc | 76 - src/mem/slicc/ast/AssignStatementAST.hh | 85 - src/mem/slicc/ast/AssignStatementAST.py | 59 + .../slicc/ast/CheckAllocateStatementAST.cc | 72 - .../slicc/ast/CheckAllocateStatementAST.hh | 82 - .../slicc/ast/CheckAllocateStatementAST.py | 47 + .../slicc/ast/CheckStopSlotsStatementAST.cc | 115 -- .../slicc/ast/CheckStopSlotsStatementAST.hh | 85 - .../slicc/ast/CheckStopSlotsStatementAST.py | 74 + src/mem/slicc/ast/ChipComponentAccessAST.cc | 244 --- src/mem/slicc/ast/ChipComponentAccessAST.hh | 101 - src/mem/slicc/ast/ChipComponentAccessAST.py | 161 ++ src/mem/slicc/ast/CopyHeadStatementAST.cc | 85 - src/mem/slicc/ast/CopyHeadStatementAST.hh | 87 - src/mem/slicc/ast/CopyHeadStatementAST.py | 52 + src/mem/slicc/ast/DeclAST.cc | 39 - src/mem/slicc/ast/DeclAST.hh | 85 - src/mem/slicc/ast/DeclAST.py | 38 + src/mem/slicc/ast/DeclListAST.cc | 86 - src/mem/slicc/ast/DeclListAST.hh | 84 - src/mem/slicc/ast/DeclListAST.py | 51 + src/mem/slicc/ast/EnqueueStatementAST.cc | 111 -- src/mem/slicc/ast/EnqueueStatementAST.hh | 93 - src/mem/slicc/ast/EnqueueStatementAST.py | 86 + src/mem/slicc/ast/EnumDeclAST.cc | 98 - src/mem/slicc/ast/EnumDeclAST.hh | 86 - src/mem/slicc/ast/EnumDeclAST.py | 71 + src/mem/slicc/ast/EnumExprAST.cc | 76 - src/mem/slicc/ast/EnumExprAST.hh | 85 - src/mem/slicc/ast/EnumExprAST.py | 53 + src/mem/slicc/ast/ExprAST.cc | 39 - src/mem/slicc/ast/ExprAST.hh | 84 - src/mem/slicc/ast/ExprAST.py | 45 + src/mem/slicc/ast/ExprStatementAST.cc | 73 - src/mem/slicc/ast/ExprStatementAST.hh | 83 - src/mem/slicc/ast/ExprStatementAST.py | 52 + src/mem/slicc/ast/FormalParamAST.cc | 72 - src/mem/slicc/ast/FormalParamAST.hh | 88 - src/mem/slicc/ast/FormalParamAST.py | 52 + src/mem/slicc/ast/FuncCallExprAST.cc | 224 --- src/mem/slicc/ast/FuncCallExprAST.hh | 89 - src/mem/slicc/ast/FuncCallExprAST.py | 168 ++ src/mem/slicc/ast/FuncDeclAST.cc | 112 -- src/mem/slicc/ast/FuncDeclAST.hh | 91 - src/mem/slicc/ast/FuncDeclAST.py | 88 + src/mem/slicc/ast/IfStatementAST.cc | 98 - src/mem/slicc/ast/IfStatementAST.hh | 89 - src/mem/slicc/ast/IfStatementAST.py | 74 + src/mem/slicc/ast/InPortDeclAST.cc | 149 -- src/mem/slicc/ast/InPortDeclAST.hh | 91 - src/mem/slicc/ast/InPortDeclAST.py | 130 ++ src/mem/slicc/ast/InfixOperatorExprAST.cc | 121 -- src/mem/slicc/ast/InfixOperatorExprAST.hh | 85 - src/mem/slicc/ast/InfixOperatorExprAST.py | 89 + src/mem/slicc/ast/LiteralExprAST.cc | 55 - src/mem/slicc/ast/LiteralExprAST.hh | 83 - src/mem/slicc/ast/LiteralExprAST.py | 55 + src/mem/slicc/ast/Location.cc | 87 - src/mem/slicc/ast/Location.hh | 93 - src/mem/slicc/ast/MachineAST.cc | 99 - src/mem/slicc/ast/MachineAST.hh | 93 - src/mem/slicc/ast/MachineAST.py | 81 + src/mem/slicc/ast/MemberExprAST.cc | 72 - src/mem/slicc/ast/MemberExprAST.hh | 83 - src/mem/slicc/ast/MemberExprAST.py | 55 + src/mem/slicc/ast/MethodCallExprAST.cc | 160 -- src/mem/slicc/ast/MethodCallExprAST.hh | 93 - src/mem/slicc/ast/MethodCallExprAST.py | 127 ++ src/mem/slicc/ast/NewExprAST.cc | 9 - src/mem/slicc/ast/NewExprAST.hh | 20 - src/mem/slicc/ast/NewExprAST.py | 47 + src/mem/slicc/ast/ObjDeclAST.cc | 137 -- src/mem/slicc/ast/ObjDeclAST.hh | 86 - src/mem/slicc/ast/ObjDeclAST.py | 94 + src/mem/slicc/ast/OutPortDeclAST.cc | 79 - src/mem/slicc/ast/OutPortDeclAST.hh | 89 - src/mem/slicc/ast/OutPortDeclAST.py | 57 + src/mem/slicc/ast/PairAST.cc | 72 - src/mem/slicc/ast/PairAST.hh | 86 - src/mem/slicc/ast/PairAST.py | 36 + src/mem/slicc/ast/PairListAST.cc | 49 - src/mem/slicc/ast/PairListAST.hh | 82 - src/mem/slicc/ast/PairListAST.py | 37 + src/mem/slicc/ast/PeekStatementAST.cc | 115 -- src/mem/slicc/ast/PeekStatementAST.hh | 91 - src/mem/slicc/ast/PeekStatementAST.py | 73 + src/mem/slicc/ast/ReturnStatementAST.cc | 79 - src/mem/slicc/ast/ReturnStatementAST.hh | 83 - src/mem/slicc/ast/ReturnStatementAST.py | 54 + src/mem/slicc/ast/StatementAST.cc | 60 - src/mem/slicc/ast/StatementAST.hh | 88 - src/mem/slicc/ast/StatementAST.py | 34 + src/mem/slicc/ast/StatementListAST.cc | 86 - src/mem/slicc/ast/StatementListAST.hh | 85 - src/mem/slicc/ast/StatementListAST.py | 46 + src/mem/slicc/ast/TransitionDeclAST.cc | 89 - src/mem/slicc/ast/TransitionDeclAST.hh | 89 - src/mem/slicc/ast/TransitionDeclAST.py | 54 + src/mem/slicc/ast/TypeAST.cc | 67 - src/mem/slicc/ast/TypeAST.hh | 83 - src/mem/slicc/ast/TypeAST.py | 53 + src/mem/slicc/ast/TypeDeclAST.cc | 86 - src/mem/slicc/ast/TypeDeclAST.hh | 86 - src/mem/slicc/ast/TypeDeclAST.py | 62 + src/mem/slicc/ast/TypeFieldAST.cc | 44 - src/mem/slicc/ast/TypeFieldAST.hh | 83 - src/mem/slicc/ast/TypeFieldAST.py | 32 + src/mem/slicc/ast/TypeFieldEnumAST.cc | 82 - src/mem/slicc/ast/TypeFieldEnumAST.hh | 86 - src/mem/slicc/ast/TypeFieldEnumAST.py | 59 + src/mem/slicc/ast/TypeFieldMemberAST.cc | 84 - src/mem/slicc/ast/TypeFieldMemberAST.hh | 91 - src/mem/slicc/ast/TypeFieldMemberAST.py | 57 + src/mem/slicc/ast/TypeFieldMethodAST.cc | 81 - src/mem/slicc/ast/TypeFieldMethodAST.hh | 87 - src/mem/slicc/ast/TypeFieldMethodAST.py | 50 + src/mem/slicc/ast/VarExprAST.cc | 76 - src/mem/slicc/ast/VarExprAST.hh | 86 - src/mem/slicc/ast/VarExprAST.py | 66 + src/mem/slicc/ast/__init__.py | 69 + src/mem/slicc/generate/__init__.py | 0 src/mem/slicc/generate/dot.py | 42 + src/mem/slicc/generate/html.py | 80 + src/mem/slicc/generate/tex.py | 71 + src/mem/slicc/generator/fileio.cc | 66 - src/mem/slicc/generator/fileio.hh | 46 - src/mem/slicc/generator/html_gen.cc | 125 -- src/mem/slicc/generator/html_gen.hh | 49 - src/mem/slicc/generator/mif_gen.cc | 1718 ----------------- src/mem/slicc/generator/mif_gen.hh | 45 - src/mem/slicc/main.cc | 246 --- src/mem/slicc/main.hh | 48 - src/mem/slicc/main.py | 108 ++ src/mem/slicc/parser.py | 669 +++++++ src/mem/slicc/parser/lexer.ll | 125 -- src/mem/slicc/parser/parser.py | 563 ------ src/mem/slicc/parser/parser.yy | 360 ---- src/mem/slicc/slicc_global.hh | 125 -- src/mem/slicc/symbols/Action.hh | 52 - src/mem/slicc/symbols/Action.py | 38 + src/mem/slicc/symbols/Event.hh | 45 - src/mem/slicc/symbols/Event.py | 34 + src/mem/slicc/symbols/Func.cc | 143 -- src/mem/slicc/symbols/Func.hh | 96 - src/mem/slicc/symbols/Func.py | 107 + src/mem/slicc/symbols/State.hh | 45 - src/mem/slicc/symbols/State.py | 34 + src/mem/slicc/symbols/StateMachine.cc | 1534 --------------- src/mem/slicc/symbols/StateMachine.hh | 156 -- src/mem/slicc/symbols/StateMachine.py | 1222 ++++++++++++ src/mem/slicc/symbols/Symbol.cc | 72 - src/mem/slicc/symbols/Symbol.hh | 100 - src/mem/slicc/symbols/Symbol.py | 78 + src/mem/slicc/symbols/SymbolTable.cc | 327 ---- src/mem/slicc/symbols/SymbolTable.hh | 121 -- src/mem/slicc/symbols/SymbolTable.py | 218 +++ src/mem/slicc/symbols/Transition.cc | 173 -- src/mem/slicc/symbols/Transition.hh | 120 -- src/mem/slicc/symbols/Transition.py | 61 + src/mem/slicc/symbols/Type.cc | 779 -------- src/mem/slicc/symbols/Type.hh | 155 -- src/mem/slicc/symbols/Type.py | 650 +++++++ src/mem/slicc/symbols/Var.cc | 57 - src/mem/slicc/symbols/Var.hh | 98 - src/mem/slicc/symbols/Var.py | 50 + src/mem/slicc/symbols/__init__.py | 38 + src/mem/slicc/util.py | 75 + util/slicc | 38 + 178 files changed, 6516 insertions(+), 15232 deletions(-) delete mode 100644 src/mem/slicc/SConscript create mode 100644 src/mem/slicc/__init__.py delete mode 100644 src/mem/slicc/ast/AST.cc delete mode 100644 src/mem/slicc/ast/AST.hh create mode 100644 src/mem/slicc/ast/AST.py delete mode 100644 src/mem/slicc/ast/ASTs.hh delete mode 100644 src/mem/slicc/ast/ActionDeclAST.cc delete mode 100644 src/mem/slicc/ast/ActionDeclAST.hh create mode 100644 src/mem/slicc/ast/ActionDeclAST.py delete mode 100644 src/mem/slicc/ast/AssignStatementAST.cc delete mode 100644 src/mem/slicc/ast/AssignStatementAST.hh create mode 100644 src/mem/slicc/ast/AssignStatementAST.py delete mode 100644 src/mem/slicc/ast/CheckAllocateStatementAST.cc delete mode 100644 src/mem/slicc/ast/CheckAllocateStatementAST.hh create mode 100644 src/mem/slicc/ast/CheckAllocateStatementAST.py delete mode 100644 src/mem/slicc/ast/CheckStopSlotsStatementAST.cc delete mode 100644 src/mem/slicc/ast/CheckStopSlotsStatementAST.hh create mode 100644 src/mem/slicc/ast/CheckStopSlotsStatementAST.py delete mode 100644 src/mem/slicc/ast/ChipComponentAccessAST.cc delete mode 100644 src/mem/slicc/ast/ChipComponentAccessAST.hh create mode 100644 src/mem/slicc/ast/ChipComponentAccessAST.py delete mode 100644 src/mem/slicc/ast/CopyHeadStatementAST.cc delete mode 100644 src/mem/slicc/ast/CopyHeadStatementAST.hh create mode 100644 src/mem/slicc/ast/CopyHeadStatementAST.py delete mode 100644 src/mem/slicc/ast/DeclAST.cc delete mode 100644 src/mem/slicc/ast/DeclAST.hh create mode 100644 src/mem/slicc/ast/DeclAST.py delete mode 100644 src/mem/slicc/ast/DeclListAST.cc delete mode 100644 src/mem/slicc/ast/DeclListAST.hh create mode 100644 src/mem/slicc/ast/DeclListAST.py delete mode 100644 src/mem/slicc/ast/EnqueueStatementAST.cc delete mode 100644 src/mem/slicc/ast/EnqueueStatementAST.hh create mode 100644 src/mem/slicc/ast/EnqueueStatementAST.py delete mode 100644 src/mem/slicc/ast/EnumDeclAST.cc delete mode 100644 src/mem/slicc/ast/EnumDeclAST.hh create mode 100644 src/mem/slicc/ast/EnumDeclAST.py delete mode 100644 src/mem/slicc/ast/EnumExprAST.cc delete mode 100644 src/mem/slicc/ast/EnumExprAST.hh create mode 100644 src/mem/slicc/ast/EnumExprAST.py delete mode 100644 src/mem/slicc/ast/ExprAST.cc delete mode 100644 src/mem/slicc/ast/ExprAST.hh create mode 100644 src/mem/slicc/ast/ExprAST.py delete mode 100644 src/mem/slicc/ast/ExprStatementAST.cc delete mode 100644 src/mem/slicc/ast/ExprStatementAST.hh create mode 100644 src/mem/slicc/ast/ExprStatementAST.py delete mode 100644 src/mem/slicc/ast/FormalParamAST.cc delete mode 100644 src/mem/slicc/ast/FormalParamAST.hh create mode 100644 src/mem/slicc/ast/FormalParamAST.py delete mode 100644 src/mem/slicc/ast/FuncCallExprAST.cc delete mode 100644 src/mem/slicc/ast/FuncCallExprAST.hh create mode 100644 src/mem/slicc/ast/FuncCallExprAST.py delete mode 100644 src/mem/slicc/ast/FuncDeclAST.cc delete mode 100644 src/mem/slicc/ast/FuncDeclAST.hh create mode 100644 src/mem/slicc/ast/FuncDeclAST.py delete mode 100644 src/mem/slicc/ast/IfStatementAST.cc delete mode 100644 src/mem/slicc/ast/IfStatementAST.hh create mode 100644 src/mem/slicc/ast/IfStatementAST.py delete mode 100644 src/mem/slicc/ast/InPortDeclAST.cc delete mode 100644 src/mem/slicc/ast/InPortDeclAST.hh create mode 100644 src/mem/slicc/ast/InPortDeclAST.py delete mode 100644 src/mem/slicc/ast/InfixOperatorExprAST.cc delete mode 100644 src/mem/slicc/ast/InfixOperatorExprAST.hh create mode 100644 src/mem/slicc/ast/InfixOperatorExprAST.py delete mode 100644 src/mem/slicc/ast/LiteralExprAST.cc delete mode 100644 src/mem/slicc/ast/LiteralExprAST.hh create mode 100644 src/mem/slicc/ast/LiteralExprAST.py delete mode 100644 src/mem/slicc/ast/Location.cc delete mode 100644 src/mem/slicc/ast/Location.hh delete mode 100644 src/mem/slicc/ast/MachineAST.cc delete mode 100644 src/mem/slicc/ast/MachineAST.hh create mode 100644 src/mem/slicc/ast/MachineAST.py delete mode 100644 src/mem/slicc/ast/MemberExprAST.cc delete mode 100644 src/mem/slicc/ast/MemberExprAST.hh create mode 100644 src/mem/slicc/ast/MemberExprAST.py delete mode 100644 src/mem/slicc/ast/MethodCallExprAST.cc delete mode 100644 src/mem/slicc/ast/MethodCallExprAST.hh create mode 100644 src/mem/slicc/ast/MethodCallExprAST.py delete mode 100644 src/mem/slicc/ast/NewExprAST.cc delete mode 100644 src/mem/slicc/ast/NewExprAST.hh create mode 100644 src/mem/slicc/ast/NewExprAST.py delete mode 100644 src/mem/slicc/ast/ObjDeclAST.cc delete mode 100644 src/mem/slicc/ast/ObjDeclAST.hh create mode 100644 src/mem/slicc/ast/ObjDeclAST.py delete mode 100644 src/mem/slicc/ast/OutPortDeclAST.cc delete mode 100644 src/mem/slicc/ast/OutPortDeclAST.hh create mode 100644 src/mem/slicc/ast/OutPortDeclAST.py delete mode 100644 src/mem/slicc/ast/PairAST.cc delete mode 100644 src/mem/slicc/ast/PairAST.hh create mode 100644 src/mem/slicc/ast/PairAST.py delete mode 100644 src/mem/slicc/ast/PairListAST.cc delete mode 100644 src/mem/slicc/ast/PairListAST.hh create mode 100644 src/mem/slicc/ast/PairListAST.py delete mode 100644 src/mem/slicc/ast/PeekStatementAST.cc delete mode 100644 src/mem/slicc/ast/PeekStatementAST.hh create mode 100644 src/mem/slicc/ast/PeekStatementAST.py delete mode 100644 src/mem/slicc/ast/ReturnStatementAST.cc delete mode 100644 src/mem/slicc/ast/ReturnStatementAST.hh create mode 100644 src/mem/slicc/ast/ReturnStatementAST.py delete mode 100644 src/mem/slicc/ast/StatementAST.cc delete mode 100644 src/mem/slicc/ast/StatementAST.hh create mode 100644 src/mem/slicc/ast/StatementAST.py delete mode 100644 src/mem/slicc/ast/StatementListAST.cc delete mode 100644 src/mem/slicc/ast/StatementListAST.hh create mode 100644 src/mem/slicc/ast/StatementListAST.py delete mode 100644 src/mem/slicc/ast/TransitionDeclAST.cc delete mode 100644 src/mem/slicc/ast/TransitionDeclAST.hh create mode 100644 src/mem/slicc/ast/TransitionDeclAST.py delete mode 100644 src/mem/slicc/ast/TypeAST.cc delete mode 100644 src/mem/slicc/ast/TypeAST.hh create mode 100644 src/mem/slicc/ast/TypeAST.py delete mode 100644 src/mem/slicc/ast/TypeDeclAST.cc delete mode 100644 src/mem/slicc/ast/TypeDeclAST.hh create mode 100644 src/mem/slicc/ast/TypeDeclAST.py delete mode 100644 src/mem/slicc/ast/TypeFieldAST.cc delete mode 100644 src/mem/slicc/ast/TypeFieldAST.hh create mode 100644 src/mem/slicc/ast/TypeFieldAST.py delete mode 100644 src/mem/slicc/ast/TypeFieldEnumAST.cc delete mode 100644 src/mem/slicc/ast/TypeFieldEnumAST.hh create mode 100644 src/mem/slicc/ast/TypeFieldEnumAST.py delete mode 100644 src/mem/slicc/ast/TypeFieldMemberAST.cc delete mode 100644 src/mem/slicc/ast/TypeFieldMemberAST.hh create mode 100644 src/mem/slicc/ast/TypeFieldMemberAST.py delete mode 100644 src/mem/slicc/ast/TypeFieldMethodAST.cc delete mode 100644 src/mem/slicc/ast/TypeFieldMethodAST.hh create mode 100644 src/mem/slicc/ast/TypeFieldMethodAST.py delete mode 100644 src/mem/slicc/ast/VarExprAST.cc delete mode 100644 src/mem/slicc/ast/VarExprAST.hh create mode 100644 src/mem/slicc/ast/VarExprAST.py create mode 100644 src/mem/slicc/ast/__init__.py create mode 100644 src/mem/slicc/generate/__init__.py create mode 100644 src/mem/slicc/generate/dot.py create mode 100644 src/mem/slicc/generate/html.py create mode 100644 src/mem/slicc/generate/tex.py delete mode 100644 src/mem/slicc/generator/fileio.cc delete mode 100644 src/mem/slicc/generator/fileio.hh delete mode 100644 src/mem/slicc/generator/html_gen.cc delete mode 100644 src/mem/slicc/generator/html_gen.hh delete mode 100644 src/mem/slicc/generator/mif_gen.cc delete mode 100644 src/mem/slicc/generator/mif_gen.hh delete mode 100644 src/mem/slicc/main.cc delete mode 100644 src/mem/slicc/main.hh create mode 100644 src/mem/slicc/main.py create mode 100644 src/mem/slicc/parser.py delete mode 100644 src/mem/slicc/parser/lexer.ll delete mode 100644 src/mem/slicc/parser/parser.py delete mode 100644 src/mem/slicc/parser/parser.yy delete mode 100644 src/mem/slicc/slicc_global.hh delete mode 100644 src/mem/slicc/symbols/Action.hh create mode 100644 src/mem/slicc/symbols/Action.py delete mode 100644 src/mem/slicc/symbols/Event.hh create mode 100644 src/mem/slicc/symbols/Event.py delete mode 100644 src/mem/slicc/symbols/Func.cc delete mode 100644 src/mem/slicc/symbols/Func.hh create mode 100644 src/mem/slicc/symbols/Func.py delete mode 100644 src/mem/slicc/symbols/State.hh create mode 100644 src/mem/slicc/symbols/State.py delete mode 100644 src/mem/slicc/symbols/StateMachine.cc delete mode 100644 src/mem/slicc/symbols/StateMachine.hh create mode 100644 src/mem/slicc/symbols/StateMachine.py delete mode 100644 src/mem/slicc/symbols/Symbol.cc delete mode 100644 src/mem/slicc/symbols/Symbol.hh create mode 100644 src/mem/slicc/symbols/Symbol.py delete mode 100644 src/mem/slicc/symbols/SymbolTable.cc delete mode 100644 src/mem/slicc/symbols/SymbolTable.hh create mode 100644 src/mem/slicc/symbols/SymbolTable.py delete mode 100644 src/mem/slicc/symbols/Transition.cc delete mode 100644 src/mem/slicc/symbols/Transition.hh create mode 100644 src/mem/slicc/symbols/Transition.py delete mode 100644 src/mem/slicc/symbols/Type.cc delete mode 100644 src/mem/slicc/symbols/Type.hh create mode 100644 src/mem/slicc/symbols/Type.py delete mode 100644 src/mem/slicc/symbols/Var.cc delete mode 100644 src/mem/slicc/symbols/Var.hh create mode 100644 src/mem/slicc/symbols/Var.py create mode 100644 src/mem/slicc/symbols/__init__.py create mode 100644 src/mem/slicc/util.py create mode 100755 util/slicc diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript index 700ab40ea6..425219580d 100644 --- a/src/mem/protocol/SConscript +++ b/src/mem/protocol/SConscript @@ -29,30 +29,56 @@ # Authors: Nathan Binkert import os -import re -import string import sys -from os.path import basename, dirname, exists, expanduser, isdir, isfile -from os.path import join as joinpath - -import SCons +from os.path import isdir, isfile, join as joinpath Import('*') if not env['RUBY']: Return() -slicc_dir = Dir('../slicc') protocol_dir = Dir('.') html_dir = Dir('html') +slicc_dir = Dir('../slicc') + +sys.path[1:1] = [ Dir('..').srcnode().abspath ] +from slicc.parser import SLICC + +slicc_depends = [] +for root,dirs,files in os.walk(slicc_dir.srcnode().abspath): + for f in files: + if f.endswith('.py'): + slicc_depends.append(File(joinpath(root, f))) # # Use SLICC # -def slicc_generator(target, source, env, for_signature): - slicc_bin = str(source[0]) - protocol = source[1].get_contents() + +def slicc_scanner(node, env, path): + contents = node.get_contents() + files = [ line.strip() for line in contents.splitlines() ] + return files + +env.Append(SCANNERS=Scanner(function=slicc_scanner,skeys=['.slicc'])) + +def slicc_emitter(target, source, env): + files = [s.srcnode().abspath for s in source[1:]] + slicc = SLICC(debug=True) + print "SLICC parsing..." + for name in slicc.load(files, verbose=True): + print " %s" % name + + hh,cc = slicc.files() + target.extend(sorted(hh)) + target.extend(sorted(cc)) + f = file('/tmp/asdf', 'w') + for t in target: + print >>f, t + return target, source + +def slicc_action(target, source, env): + protocol = source[0].get_contents() pdir = str(protocol_dir) hdir = str(html_dir) @@ -61,31 +87,31 @@ def slicc_generator(target, source, env, for_signature): if not isdir(hdir): os.mkdir(hdir) - do_html = "html" - cmdline = [ slicc_bin, pdir, hdir, protocol, do_html ] - cmdline += [ str(s) for s in source[2:] ] - cmdline = ' '.join(cmdline) - return cmdline + slicc = SLICC(debug=True) + files = [str(s) for s in source[1:]] + slicc.load(files, verbose=False) -slicc_builder = Builder(generator=slicc_generator) + print "SLICC Generator pass 1..." + slicc.findMachines() + + print "SLICC Generator pass 2..." + slicc.generate() + + print "SLICC writing C++ files..." + slicc.writeCodeFiles(pdir) + + print "SLICC writing HTML files..." + slicc.writeHTMLFiles(hdir) + +slicc_builder = Builder(action=slicc_action, emitter=slicc_emitter) protocol = env['PROTOCOL'] sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"), protocol_dir.File("%s.slicc" % protocol) ] -execfile(slicc_dir.File('parser/parser.py').srcnode().abspath) - -sm_files = read_slicc([s.srcnode().abspath for s in sources]) -sm_files = [ protocol_dir.File(f) for f in sm_files ] - -hh, cc = scan([s.srcnode().abspath for s in sm_files]) -hh = [ protocol_dir.File(f) for f in hh ] -cc = [ protocol_dir.File(f) for f in cc ] - -slicc_bin = slicc_dir.File("slicc") - env.Append(BUILDERS={'SLICC' : slicc_builder}) -env.SLICC(hh + cc, [ slicc_bin, Value(protocol) ] + sm_files) +nodes = env.SLICC([], [ Value(protocol) ] + sources) +env.Depends(nodes, slicc_depends) -for f in cc: +for f in sorted(s for s in nodes if str(s).endswith('.cc')): Source(f) diff --git a/src/mem/slicc/SConscript b/src/mem/slicc/SConscript deleted file mode 100644 index e26ceb9794..0000000000 --- a/src/mem/slicc/SConscript +++ /dev/null @@ -1,129 +0,0 @@ -# -*- mode:python -*- - -# Copyright (c) 2009 The Hewlett-Packard Development Company -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Nathan Binkert - -import os -import re -import string -import sys - -from os.path import basename, dirname, exists, expanduser, isdir, isfile -from os.path import join as joinpath - -import SCons - -Import('*') - -if not env['RUBY']: - Return() - -common_dir = Dir('../gems_common') - -# -# Build SLICC -# -slicc_env = env.Clone() -slicc_env['CPPDEFINES'] = '' -slicc_env['CPPPATH'] = Dir('../..') -slicc_env.Append(CCFLAGS=['-g', '-O0']) -slicc_env.Append(CPPDEFINES=['DEBUG', 'TRACING_ON=1']) -slicc_env['LIBS'] = '' -slicc_env['LIBPATH'] = '' -all_slicc_sources = [] -def SliccSource(filename): - if filename.endswith('.ll') or filename.endswith('.yy'): - slicc_env.CXXFile(filename) - filename = filename[:-2] + "cc" - x = slicc_env.StaticObject(filename) - all_slicc_sources.append(x) - return x - -# BE CAREFUL WITH THE ORDER OF FILENAMES HERE. SLICC IS VERY FRAGILE -# BECAUSE IT VIOLATES ESTABLISHED RULES ABOUT HOW YOU'RE ALLOWED TO -# CREATE STATIC OBJECTS. (SLICC HAS DEPENDENCIES DURING STATIC OBJECT -# CONSTRUCTION ACROSS FILES. THAT'S A NO-NO.) WITH THIS FILE ORDER, -# WE GET LUCKY AND OBJECTS GET CONSTRUCTED IN THE RIGHT ORDER. -SliccSource('parser/parser.yy') -SliccSource('parser/lexer.ll') -SliccSource('main.cc') -SliccSource('symbols/Func.cc') -SliccSource('symbols/StateMachine.cc') -SliccSource('symbols/Symbol.cc') -SliccSource('symbols/SymbolTable.cc') -SliccSource('symbols/Transition.cc') -SliccSource('symbols/Type.cc') -SliccSource('symbols/Var.cc') -SliccSource('generator/fileio.cc') -SliccSource('generator/html_gen.cc') -SliccSource('generator/mif_gen.cc') -SliccSource('ast/AST.cc') -SliccSource('ast/ActionDeclAST.cc') -SliccSource('ast/AssignStatementAST.cc') -SliccSource('ast/CheckAllocateStatementAST.cc') -SliccSource('ast/CheckStopSlotsStatementAST.cc') -SliccSource('ast/ChipComponentAccessAST.cc') -SliccSource('ast/CopyHeadStatementAST.cc') -SliccSource('ast/DeclAST.cc') -SliccSource('ast/DeclListAST.cc') -SliccSource('ast/EnqueueStatementAST.cc') -SliccSource('ast/EnumDeclAST.cc') -SliccSource('ast/EnumExprAST.cc') -SliccSource('ast/ExprAST.cc') -SliccSource('ast/ExprStatementAST.cc') -SliccSource('ast/FormalParamAST.cc') -SliccSource('ast/FuncCallExprAST.cc') -SliccSource('ast/FuncDeclAST.cc') -SliccSource('ast/IfStatementAST.cc') -SliccSource('ast/InPortDeclAST.cc') -SliccSource('ast/InfixOperatorExprAST.cc') -SliccSource('ast/LiteralExprAST.cc') -SliccSource('ast/Location.cc') -SliccSource('ast/MachineAST.cc') -SliccSource('ast/MemberExprAST.cc') -SliccSource('ast/MethodCallExprAST.cc') -SliccSource('ast/NewExprAST.cc') -SliccSource('ast/ObjDeclAST.cc') -SliccSource('ast/OutPortDeclAST.cc') -SliccSource('ast/PairAST.cc') -SliccSource('ast/PairListAST.cc') -SliccSource('ast/PeekStatementAST.cc') -SliccSource('ast/ReturnStatementAST.cc') -SliccSource('ast/StatementAST.cc') -SliccSource('ast/StatementListAST.cc') -SliccSource('ast/TransitionDeclAST.cc') -SliccSource('ast/TypeAST.cc') -SliccSource('ast/TypeDeclAST.cc') -SliccSource('ast/TypeFieldAST.cc') -SliccSource('ast/TypeFieldEnumAST.cc') -SliccSource('ast/TypeFieldMemberAST.cc') -SliccSource('ast/TypeFieldMethodAST.cc') -SliccSource('ast/VarExprAST.cc') - -slicc_bin = File('slicc') -slicc_env.Program(slicc_bin, all_slicc_sources + [ common_dir.File('util.o') ]) diff --git a/src/mem/slicc/__init__.py b/src/mem/slicc/__init__.py new file mode 100644 index 0000000000..8ce04e77de --- /dev/null +++ b/src/mem/slicc/__init__.py @@ -0,0 +1,25 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/mem/slicc/ast/AST.cc b/src/mem/slicc/ast/AST.cc deleted file mode 100644 index e893c453a7..0000000000 --- a/src/mem/slicc/ast/AST.cc +++ /dev/null @@ -1,39 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * AST.C - * - * Description: See AST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/AST.hh" diff --git a/src/mem/slicc/ast/AST.hh b/src/mem/slicc/ast/AST.hh deleted file mode 100644 index 33c9b84ed3..0000000000 --- a/src/mem/slicc/ast/AST.hh +++ /dev/null @@ -1,94 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * AST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef AST_H -#define AST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Vector.hh" -#include "mem/gems_common/Map.hh" -#include "mem/slicc/ast/Location.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -class AST { -public: - // Constructors - AST(Map pairs) { m_pairs = pairs; }; - AST() {}; - - // Destructor - virtual ~AST() {}; - - // Public Methods - virtual void print(ostream& out) const = 0; - void error(string err_msg) const { m_location.error(err_msg); }; - string embedError(string err_msg) const { return m_location.embedError(err_msg); }; - void warning(string err_msg) const { m_location.warning(err_msg); }; - - const Location& getLocation() const { return m_location; }; - - const Map& getPairs() const { return m_pairs; }; - Map& getPairs() { return m_pairs; }; - -private: - // Private Methods - - // Private copy constructor and assignment operator - // AST(const AST& obj); - // AST& operator=(const AST& obj); - - // Data Members (m_ prefix) - Location m_location; - Map m_pairs; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const AST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const AST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //AST_H diff --git a/src/mem/slicc/ast/AST.py b/src/mem/slicc/ast/AST.py new file mode 100644 index 0000000000..5b1b124cdc --- /dev/null +++ b/src/mem/slicc/ast/AST.py @@ -0,0 +1,63 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.util import PairContainer, Location + +class AST(PairContainer): + def __init__(self, slicc, pairs=None): + self.slicc = slicc + self.location = Location(slicc.current_file, slicc.lexer.lineno) + self.pairs = {} + if pairs: + self.pairs.update(getattr(pairs, "pairs", pairs)) + + @property + def symtab(self): + return self.slicc.symtab + + @property + def state_machine(self): + return self.slicc.symtab.state_machine + + def warning(self, message, *args): + self.location.warning(message, *args) + + def error(self, message, *args): + self.location.error(message, *args) + + def embedError(self, message, *args): + if args: + message = message % args + code = code_formatter() + code(''' +cerr << "Runtime Error at ${{self.location}}, Ruby Time: " << g_eventQueue_ptr->getTime() << ": "<< $message << ", PID: " << getpid() << endl; +char c; cerr << "press return to continue." << endl; cin.get(c); abort(); +''') + + return code diff --git a/src/mem/slicc/ast/ASTs.hh b/src/mem/slicc/ast/ASTs.hh deleted file mode 100644 index 3363fbb091..0000000000 --- a/src/mem/slicc/ast/ASTs.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#ifndef ASTs_H -#define ASTs_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/main.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/AST.hh" - -#include "mem/slicc/ast/MachineAST.hh" - -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/FormalParamAST.hh" - -#include "mem/slicc/ast/DeclListAST.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/ActionDeclAST.hh" -#include "mem/slicc/ast/InPortDeclAST.hh" -#include "mem/slicc/ast/OutPortDeclAST.hh" -#include "mem/slicc/ast/TransitionDeclAST.hh" -#include "mem/slicc/ast/EnumDeclAST.hh" -#include "mem/slicc/ast/TypeDeclAST.hh" -#include "mem/slicc/ast/ObjDeclAST.hh" -#include "mem/slicc/ast/FuncDeclAST.hh" - -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/TypeFieldMethodAST.hh" -#include "mem/slicc/ast/TypeFieldMemberAST.hh" -#include "mem/slicc/ast/TypeFieldEnumAST.hh" - -#include "mem/slicc/ast/PairAST.hh" -#include "mem/slicc/ast/PairListAST.hh" - -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/EnumExprAST.hh" -#include "mem/slicc/ast/LiteralExprAST.hh" -#include "mem/slicc/ast/MemberExprAST.hh" -#include "mem/slicc/ast/InfixOperatorExprAST.hh" -#include "mem/slicc/ast/FuncCallExprAST.hh" -#include "mem/slicc/ast/MethodCallExprAST.hh" -#include "mem/slicc/ast/NewExprAST.hh" - -#include "mem/slicc/ast/ChipComponentAccessAST.hh" - -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprStatementAST.hh" -#include "mem/slicc/ast/AssignStatementAST.hh" -#include "mem/slicc/ast/EnqueueStatementAST.hh" -#include "mem/slicc/ast/IfStatementAST.hh" -#include "mem/slicc/ast/PeekStatementAST.hh" -#include "mem/slicc/ast/CopyHeadStatementAST.hh" -#include "mem/slicc/ast/CheckAllocateStatementAST.hh" -#include "mem/slicc/ast/CheckStopSlotsStatementAST.hh" -#include "mem/slicc/ast/ReturnStatementAST.hh" - -#endif //ASTs_H diff --git a/src/mem/slicc/ast/ActionDeclAST.cc b/src/mem/slicc/ast/ActionDeclAST.cc deleted file mode 100644 index e46412ff7d..0000000000 --- a/src/mem/slicc/ast/ActionDeclAST.cc +++ /dev/null @@ -1,98 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ActionDeclAST.C - * - * Description: See ActionDeclAST.hh - * - * $Id$ - * - */ - - -#include "mem/slicc/ast/ActionDeclAST.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/slicc/ast/StatementListAST.hh" - -ActionDeclAST::ActionDeclAST(string* ident_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr) - : DeclAST(pairs_ptr) -{ - m_ident_ptr = ident_ptr; - m_statement_list_ptr = statement_list_ptr; -} - -ActionDeclAST::~ActionDeclAST() -{ - delete m_ident_ptr; - delete m_statement_list_ptr; -} - -void ActionDeclAST::generate() -{ - Map resource_list; - if (m_statement_list_ptr != NULL) { - string code; - - // Add new local vars - g_sym_table.pushFrame(); - - Type* type_ptr = g_sym_table.getType("Address"); - - if (type_ptr == NULL) { - error("Type 'Address' not declared."); - } - - g_sym_table.newSym(new Var("address", getLocation(), type_ptr, "addr", getPairs())); - - // Don't allows returns in actions - m_statement_list_ptr->generate(code, NULL); - - getPairs().add("c_code", code); - - m_statement_list_ptr->findResources(resource_list); - - g_sym_table.popFrame(); - } - - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr == NULL) { - error("Action declaration not part of a machine."); - } else { - machine_ptr->addAction(new Action(*m_ident_ptr, resource_list, getLocation(), getPairs())); - } - -} - -void ActionDeclAST::print(ostream& out) const -{ - out << "[ActionDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/ActionDeclAST.hh b/src/mem/slicc/ast/ActionDeclAST.hh deleted file mode 100644 index 4970ee254a..0000000000 --- a/src/mem/slicc/ast/ActionDeclAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ActionDeclAST.hh - * - * Description: - * - * $Id: ActionDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef ActionDeclAST_H -#define ActionDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" - -class StatementListAST; - -class ActionDeclAST : public DeclAST { -public: - // Constructors - ActionDeclAST(string* ident_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr); - - // Destructor - ~ActionDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ActionDeclAST(const ActionDeclAST& obj); - ActionDeclAST& operator=(const ActionDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - StatementListAST* m_statement_list_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ActionDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ActionDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ActionDeclAST_H diff --git a/src/mem/slicc/ast/ActionDeclAST.py b/src/mem/slicc/ast/ActionDeclAST.py new file mode 100644 index 0000000000..18bf443b92 --- /dev/null +++ b/src/mem/slicc/ast/ActionDeclAST.py @@ -0,0 +1,72 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Action, Type, Var + +class ActionDeclAST(DeclAST): + def __init__(self, slicc, ident, pairs, statement_list): + super(ActionDeclAST, self).__init__(slicc, pairs) + self.ident = ident + self.statement_list = statement_list + + def __repr__(self): + return "[ActionDecl: %r]" % (self.ident) + + def generate(self): + resources = {} + if self.statement_list: + # Add new local vars + self.symtab.pushFrame() + + addr_type = self.symtab.find("Address", Type) + + if addr_type is None: + self.error("Type 'Address' not declared.") + + var = Var(self.symtab, "address", self.location, addr_type, + "addr", self.pairs) + self.symtab.newSymbol(var) + + # Do not allows returns in actions + code = code_formatter() + self.statement_list.generate(code, None) + self.pairs["c_code"] = str(code) + + self.statement_list.findResources(resources) + + self.symtab.popFrame() + + machine = self.symtab.state_machine + if machine is None: + self.error("Action declaration not part of a machine.") + + action = Action(self.symtab, self.ident, resources, self.location, + self.pairs) + machine.addAction(action) diff --git a/src/mem/slicc/ast/AssignStatementAST.cc b/src/mem/slicc/ast/AssignStatementAST.cc deleted file mode 100644 index 8cf42aa633..0000000000 --- a/src/mem/slicc/ast/AssignStatementAST.cc +++ /dev/null @@ -1,76 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * AssignStatementAST.C - * - * Description: See AssignStatementAST.hh - * - * $Id: AssignStatementAST.C,v 3.2 2003/08/01 18:38:19 beckmann Exp $ - * - */ - -#include "mem/slicc/ast/AssignStatementAST.hh" - -AssignStatementAST::AssignStatementAST(ExprAST* lvalue_ptr, ExprAST* rvalue_ptr) - : StatementAST() -{ - m_lvalue_ptr = lvalue_ptr; - m_rvalue_ptr = rvalue_ptr; -} - -AssignStatementAST::~AssignStatementAST() -{ - delete m_lvalue_ptr; - delete m_rvalue_ptr; -} - -void AssignStatementAST::generate(string& code, Type* return_type_ptr) const -{ - code += indent_str(); - Type* lvalue_type_ptr = m_lvalue_ptr->generate(code); - code += " = "; - Type* rvalue_type_ptr = m_rvalue_ptr->generate(code); - code += ";\n"; - - if (lvalue_type_ptr != rvalue_type_ptr) { - // FIXME - beckmann - // the following if statement is a hack to allow NetDest objects to be assigned to Sets - // this allows for the previous NetworkMessage Destiantion 'Set class' to migrate to the - // new NetworkMessage Destiantion 'NetDest class' - if (lvalue_type_ptr->toString() != "NetDest" && rvalue_type_ptr->toString() != "Set") { - error("Assignment type mismatch '" + lvalue_type_ptr->toString() + "' and '" + rvalue_type_ptr->toString() + "'"); - } - } -} - -void AssignStatementAST::print(ostream& out) const -{ - out << "[AssignStatementAST: " << *m_lvalue_ptr << " := " << *m_rvalue_ptr << "]"; -} diff --git a/src/mem/slicc/ast/AssignStatementAST.hh b/src/mem/slicc/ast/AssignStatementAST.hh deleted file mode 100644 index 2c19da831f..0000000000 --- a/src/mem/slicc/ast/AssignStatementAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * AssignStatementAST.hh - * - * Description: - * - * $Id: AssignStatementAST.hh,v 3.2 2001/12/12 01:00:09 milo Exp $ - * - */ - -#ifndef ASSIGNSTATEMENTAST_H -#define ASSIGNSTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - - - -class AssignStatementAST : public StatementAST { -public: - // Constructors - AssignStatementAST(ExprAST* lvalue_ptr, ExprAST* rvalue_ptr); - - // Destructor - ~AssignStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - AssignStatementAST(const AssignStatementAST& obj); - AssignStatementAST& operator=(const AssignStatementAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_lvalue_ptr; - ExprAST* m_rvalue_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const AssignStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const AssignStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ASSIGNSTATEMENTAST_H diff --git a/src/mem/slicc/ast/AssignStatementAST.py b/src/mem/slicc/ast/AssignStatementAST.py new file mode 100644 index 0000000000..f8e77b03b4 --- /dev/null +++ b/src/mem/slicc/ast/AssignStatementAST.py @@ -0,0 +1,59 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.StatementAST import StatementAST + +class AssignStatementAST(StatementAST): + def __init__(self, slicc, lvalue, rvalue): + super(AssignStatementAST, self).__init__(slicc) + self.lvalue = lvalue + self.rvalue = rvalue + + def __repr__(self): + return "[AssignStatementAST: %r := %r]" % (self.lvalue, self.rvalue) + + def generate(self, code, return_type): + lcode = code_formatter() + rcode = code_formatter() + + ltype = self.lvalue.generate(lcode) + rtype = self.rvalue.generate(rcode) + + code("$lcode = $rcode;") + + if ltype != rtype: + # FIXME - beckmann + # the following if statement is a hack to allow NetDest + # objects to be assigned to Sets this allows for the + # previous NetworkMessage Destiantion 'Set class' to + # migrate to the new NetworkMessage Destiantion 'NetDest + # class' + if str(ltype) != "NetDest" and str(rtype) != "Set": + self.error("Assignment type mismatch '%s' and '%s'", + ltype, rtype) diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.cc b/src/mem/slicc/ast/CheckAllocateStatementAST.cc deleted file mode 100644 index 1f498efe21..0000000000 --- a/src/mem/slicc/ast/CheckAllocateStatementAST.cc +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/ast/CheckAllocateStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/gems_common/util.hh" - -CheckAllocateStatementAST::CheckAllocateStatementAST(VarExprAST* variable) - : StatementAST() -{ - m_variable = variable; -} - -CheckAllocateStatementAST::~CheckAllocateStatementAST() -{ - delete m_variable; -} - -void CheckAllocateStatementAST::generate(string& code, Type* return_type_ptr) const -{ - // FIXME - check the type of the variable - - // Make sure the variable is valid - m_variable->getVar(); -} - -void CheckAllocateStatementAST::findResources(Map& resource_list) const -{ - Var* var_ptr = m_variable->getVar(); - int res_count = 0; - if (resource_list.exist(var_ptr)) { - res_count = atoi((resource_list.lookup(var_ptr)).c_str()); - } - resource_list.add(var_ptr, int_to_string(res_count+1)); -} - -void CheckAllocateStatementAST::print(ostream& out) const -{ - out << "[CheckAllocateStatementAst: " << *m_variable << "]"; -} diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.hh b/src/mem/slicc/ast/CheckAllocateStatementAST.hh deleted file mode 100644 index 1df8535148..0000000000 --- a/src/mem/slicc/ast/CheckAllocateStatementAST.hh +++ /dev/null @@ -1,82 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#ifndef CHECKALLOCATESTATEMENTAST_H -#define CHECKALLOCATESTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class VarExprAST; -class Var; - -class CheckAllocateStatementAST : public StatementAST { -public: - // Constructors - CheckAllocateStatementAST(VarExprAST* variable); - - // Destructor - ~CheckAllocateStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - CheckAllocateStatementAST(const CheckAllocateStatementAST& obj); - CheckAllocateStatementAST& operator=(const CheckAllocateStatementAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_variable; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const CheckAllocateStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const CheckAllocateStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //CHECKALLOCATESTATEMENTAST_H diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.py b/src/mem/slicc/ast/CheckAllocateStatementAST.py new file mode 100644 index 0000000000..b96153b0a2 --- /dev/null +++ b/src/mem/slicc/ast/CheckAllocateStatementAST.py @@ -0,0 +1,47 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST + +class CheckAllocateStatementAST(StatementAST): + def __init__(self, slicc, variable): + super(StatementAST, self).__init__(slicc) + self.variable = variable + + def __repr__(self): + return "[CheckAllocateStatementAst: %r]" % self.variable + + def generate(self, code, return_type): + # FIXME - check the type of the variable + + # Make sure the variable is valid + self.variable.var + + def findResources(self, resources): + var = self.variable.var + res_count = int(resources.get(var, 0)) + resources[var] = str(res_count + 1) diff --git a/src/mem/slicc/ast/CheckStopSlotsStatementAST.cc b/src/mem/slicc/ast/CheckStopSlotsStatementAST.cc deleted file mode 100644 index 38dc449d6b..0000000000 --- a/src/mem/slicc/ast/CheckStopSlotsStatementAST.cc +++ /dev/null @@ -1,115 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/ast/CheckStopSlotsStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/PairListAST.hh" - -CheckStopSlotsStatementAST::CheckStopSlotsStatementAST(VarExprAST* variable, string* condStr, string* bankStr) - : StatementAST() -{ - m_variable = variable; - m_condStr_ptr = condStr; - m_bankStr_ptr = bankStr; -} - -CheckStopSlotsStatementAST::~CheckStopSlotsStatementAST() -{ - delete m_variable; - delete m_condStr_ptr; - delete m_bankStr_ptr; -} - -void CheckStopSlotsStatementAST::generate(string& code, Type* return_type_ptr) const -{ - - // Make sure the variable is valid - m_variable->getVar(); - -} - -void CheckStopSlotsStatementAST::findResources(Map& resource_list) const -{ - Type* type_ptr; - - Var* var_ptr = m_variable->getVar(); - string check_code; - - if (*m_condStr_ptr == "((*in_msg_ptr)).m_isOnChipSearch") { - check_code += " const Response9Msg* in_msg_ptr;\n"; - check_code += " in_msg_ptr = dynamic_cast(((*(m_chip_ptr->m_L2Cache_responseToL2Cache9_vec[m_version]))).peek());\n"; - check_code += " assert(in_msg_ptr != NULL);\n"; - } - - check_code += " if ("; - check_code += *m_condStr_ptr; - check_code += ") {\n"; - - check_code += " if (!"; - type_ptr = m_variable->generate(check_code); - check_code += ".isDisableSPossible((((*(m_chip_ptr->m_DNUCAmover_ptr))).getBankPos("; - check_code += *m_bankStr_ptr; - check_code += ")))) {\n"; - if(CHECK_INVALID_RESOURCE_STALLS) { - check_code += " assert(priority >= "; - type_ptr = m_variable->generate(check_code); - check_code += ".getPriority());\n"; - } - check_code += " return TransitionResult_ResourceStall;\n"; - check_code += " }\n"; - check_code += " } else {\n"; - check_code += " if (!"; - type_ptr = m_variable->generate(check_code); - check_code += ".isDisableFPossible((((*(m_chip_ptr->m_DNUCAmover_ptr))).getBankPos("; - check_code += *m_bankStr_ptr; - check_code += ")))) {\n"; - if(CHECK_INVALID_RESOURCE_STALLS) { - check_code += " assert(priority >= "; - type_ptr = m_variable->generate(check_code); - check_code += ".getPriority());\n"; - } - check_code += " return TransitionResult_ResourceStall;\n"; - check_code += " }\n"; - check_code += " }\n"; - - assert(!resource_list.exist(var_ptr)); - resource_list.add(var_ptr, check_code); - -} - -void CheckStopSlotsStatementAST::print(ostream& out) const -{ - out << "[CheckStopSlotsStatementAst: " << *m_variable << "]"; -} diff --git a/src/mem/slicc/ast/CheckStopSlotsStatementAST.hh b/src/mem/slicc/ast/CheckStopSlotsStatementAST.hh deleted file mode 100644 index 6de068caa9..0000000000 --- a/src/mem/slicc/ast/CheckStopSlotsStatementAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#ifndef CHECKSTOPSLOTSSTATEMENTAST_H -#define CHECKSTOPSLOTSSTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class VarExprAST; -class Var; - -class CheckStopSlotsStatementAST : public StatementAST { -public: - // Constructors - CheckStopSlotsStatementAST(VarExprAST* variable, string* condStr, string* bankStr); - - // Destructor - ~CheckStopSlotsStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - CheckStopSlotsStatementAST(const CheckStopSlotsStatementAST& obj); - CheckStopSlotsStatementAST& operator=(const CheckStopSlotsStatementAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_variable; - string* m_condStr_ptr; - string* m_bankStr_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const CheckStopSlotsStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const CheckStopSlotsStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //CHECKSTOPSLOTSSTATEMENTAST_H diff --git a/src/mem/slicc/ast/CheckStopSlotsStatementAST.py b/src/mem/slicc/ast/CheckStopSlotsStatementAST.py new file mode 100644 index 0000000000..307fbd6a15 --- /dev/null +++ b/src/mem/slicc/ast/CheckStopSlotsStatementAST.py @@ -0,0 +1,74 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST + +class CheckStopSlotsStatementAST(StatementAST): + def __init__(self, slicc, variable, condStr, bankStr): + super(StatementAST, self).__init__(slicc) + self.variable = variable + self.condStr = condStr + self.bankStr = bankStr + + def __repr__(self): + return "[CheckStopSlotsStatementAst: %r]" % self.variable + + def generate(self, code, return_type): + # Make sure the variable is valid + self.variable.var + + def findResources(self, resources): + var = self.variable.var + assert var not in self.resources + + check_code = code_formatter() + if self.condStr == "((*in_msg_ptr)).m_isOnChipSearch": + check_code(''' +const Response9Msg* in_msg_ptr = + dynamic_cast(((*(m_chip_ptr.m_L2Cache_responseToL2Cache9_vec[m_version]))).peek()); +assert(in_msg_ptr != NULL); +''') + + vcode = self.variable.inline() + bank = self.bankStr + cond = self.condStr + + check_code(''' +if ($cond) { + auto pos = m_chip_ptr.m_DNUCAmover_ptr->getBankPos($bank) + + if (!$vcode.isDisableSPossible(pos)) { + return TransitionResult_ResourceStall; + } +} else { + if (!$vcode.isDisableFPossible(pos)) { + return TransitionResult_ResourceStall; + } +} +''') + + resources[var] = str(check_code) diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.cc b/src/mem/slicc/ast/ChipComponentAccessAST.cc deleted file mode 100644 index 61dccf2c09..0000000000 --- a/src/mem/slicc/ast/ChipComponentAccessAST.cc +++ /dev/null @@ -1,244 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ChipComponentAccessAST.C - * - * Description: See ChipComponentAccessAST.hh - * - * $Id: ChipComponentAccessAST.C 1.9 04/06/18 21:00:08-00:00 beckmann@cottons.cs.wisc.edu $ - * - */ - -#include "mem/slicc/ast/ChipComponentAccessAST.hh" - -ChipComponentAccessAST::ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector* expr_vec_ptr) - - : ExprAST() -{ - m_chip_ver_expr_ptr = NULL; - m_mach_var_ptr = machine; - m_comp_var_ptr = component; - m_mach_ver_expr_ptr = mach_version; - m_expr_vec_ptr = expr_vec_ptr; - m_proc_name_ptr = proc_name; - m_field_name_ptr = NULL; -} - -ChipComponentAccessAST::ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name) - - : ExprAST() -{ - m_chip_ver_expr_ptr = NULL; - m_mach_var_ptr = machine; - m_comp_var_ptr = component; - m_mach_ver_expr_ptr = mach_version; - m_expr_vec_ptr = NULL; - m_proc_name_ptr = NULL; - m_field_name_ptr = field_name; -} - -ChipComponentAccessAST::ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector* expr_vec_ptr) - - : ExprAST() -{ - m_chip_ver_expr_ptr = chip_version; - m_mach_var_ptr = machine; - m_comp_var_ptr = component; - m_mach_ver_expr_ptr = mach_version; - m_expr_vec_ptr = expr_vec_ptr; - m_proc_name_ptr = proc_name; - m_field_name_ptr = NULL; -} - -ChipComponentAccessAST::ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name) - - : ExprAST() -{ - m_chip_ver_expr_ptr = chip_version; - m_mach_var_ptr = machine; - m_comp_var_ptr = component; - m_mach_ver_expr_ptr = mach_version; - m_expr_vec_ptr = NULL; - m_proc_name_ptr = NULL; - m_field_name_ptr = field_name; -} - - - -ChipComponentAccessAST::~ChipComponentAccessAST() -{ - if (m_expr_vec_ptr != NULL) { - int size = m_expr_vec_ptr->size(); - for(int i=0; igetName(), m_comp_var_ptr->getName()); - - string orig_code = v->getCode(); - string working_code; - - if (m_chip_ver_expr_ptr != NULL) { - // replace m_chip_ptr with specified chip - - unsigned int t = orig_code.find("m_chip_ptr"); - assert(t != string::npos); - string code_temp0 = orig_code.substr(0, t); - string code_temp1 = orig_code.substr(t+10); - - working_code += code_temp0; - working_code += "g_system_ptr->getChip("; - m_chip_ver_expr_ptr->generate(working_code); - working_code += ")"; - working_code += code_temp1; - } - else { - working_code += orig_code; - } - - // replace default "m_version" with the version we really want - unsigned int tmp_uint = working_code.find("m_version"); - assert(tmp_uint != string::npos); - string code_temp2 = working_code.substr(0, tmp_uint); - string code_temp3 = working_code.substr(tmp_uint+9); - - code += code_temp2; - code += "("; - m_mach_ver_expr_ptr->generate(code); - code += ")"; - code += code_temp3; - code += ")"; - - if (m_proc_name_ptr != NULL) { - // method call - code += "."; - - Vector paramTypes; - - // generate code - int actual_size = m_expr_vec_ptr->size(); - code += (*m_proc_name_ptr) + "("; - for(int i=0; igenerate(code); - paramTypes.insertAtBottom(actual_type_ptr); - } - code += ")"; - - Type* obj_type_ptr = v->getType(); - string methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes); - - // Verify that this is a method of the object - if (!obj_type_ptr->methodExist(methodId)) { - error("Invalid method call: Type '" + obj_type_ptr->toString() + "' does not have a method '" + methodId + "'"); - } - - int expected_size = obj_type_ptr->methodParamType(methodId).size(); - if (actual_size != expected_size) { - // Right number of parameters - ostringstream err; - err << "Wrong number of parameters for function name: '" << *m_proc_name_ptr << "'"; - err << ", expected: "; - err << expected_size; - err << ", actual: "; - err << actual_size; - error(err.str()); - } - - for(int i=0; imethodParamType(methodId)[i]; - if (actual_type_ptr != expected_type_ptr) { - (*m_expr_vec_ptr)[i]->error("Type mismatch: expected: " + expected_type_ptr->toString() + - " actual: " + actual_type_ptr->toString()); - } - } - - // Return the return type of the method - ret_type_ptr = obj_type_ptr->methodReturnType(methodId); - } - else if (m_field_name_ptr != NULL) { - Type* obj_type_ptr = v->getType(); - code += ").m_" + (*m_field_name_ptr); - - // Verify that this is a valid field name for this type - if (!obj_type_ptr->dataMemberExist(*m_field_name_ptr)) { - error("Invalid object field: Type '" + obj_type_ptr->toString() + "' does not have data member " + *m_field_name_ptr); - } - - // Return the type of the field - ret_type_ptr = obj_type_ptr->dataMemberType(*m_field_name_ptr); - } - else { - assert(0); - } - - return ret_type_ptr; -} - -void ChipComponentAccessAST::findResources(Map& resource_list) const -{ - -} - -void ChipComponentAccessAST::print(ostream& out) const -{ - out << "[ChipAccessExpr: " << *m_expr_vec_ptr << "]"; -} diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.hh b/src/mem/slicc/ast/ChipComponentAccessAST.hh deleted file mode 100644 index 1f22a79e48..0000000000 --- a/src/mem/slicc/ast/ChipComponentAccessAST.hh +++ /dev/null @@ -1,101 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * - * - * Description: - * - * $Id: ChipComponentAccessAST.hh 1.8 04/06/18 21:00:08-00:00 beckmann@cottons.cs.wisc.edu $ - * - */ - -#ifndef ChipComponentAccessAST_H -#define ChipComponentAccessAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class ChipComponentAccessAST : public ExprAST { -public: - // Constructors - - // method call from local chip - ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector* expr_vec_ptr); - // member access from local chip - ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name); - - // method call from specified chip - ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector* expr_vec_ptr); - - // member access from specified chip - ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name); - - // Destructor - ~ChipComponentAccessAST(); - - // Public Methods - Type* generate(string& code) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ChipComponentAccessAST(const ChipComponentAccessAST& obj); - ChipComponentAccessAST& operator=(const ChipComponentAccessAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_mach_var_ptr; - VarExprAST* m_comp_var_ptr; - ExprAST* m_mach_ver_expr_ptr; - ExprAST* m_chip_ver_expr_ptr; - Vector* m_expr_vec_ptr; - string* m_proc_name_ptr; - string* m_field_name_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ChipComponentAccessAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ChipComponentAccessAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif // ChipComponentAccessAST_H diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.py b/src/mem/slicc/ast/ChipComponentAccessAST.py new file mode 100644 index 0000000000..841220c948 --- /dev/null +++ b/src/mem/slicc/ast/ChipComponentAccessAST.py @@ -0,0 +1,161 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import re + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Type + +class ChipComponentAccessAST(ExprAST): + def __init__(self, slicc, machine, mach_version, component): + super(ChipComponentAccessAST, self).__init__(slicc) + self.mach_var = machine + self.comp_var = component + self.mach_ver_expr = mach_version + + def __repr__(self): + return "[ChipAccessExpr: %r]" % self.expr_vec + + def generate(self, code): + void_type = self.symtab.find("void", Type) + + mname = self.mach_var.name + cname = self.comp_var.name + var = self.symtab.machine_components[mname][cname] + + vcode = str(var.code) + + if self.chip_ver_expr is not None: + # replace self.chip with specified chip + gcode = "g_system.getChip(%s)" % self.chip_ver_expr.inline() + vcode = re.sub("m_chip", gcode, vcode) + + # replace default "m_version" with the version we really want + gcode = "(%s)" % self.mach_ver_expr.inline() + vcode = re.sub("m_version", gcode, vcode) + + return_type, gcode = self.generate_access(var) + code("($vcode)$gcode") + return return_type + +class ChipMethodAccessAST(ChipComponentAccessAST): + def __init__(self, slicc, chip_version, machine, mach_version, component, + proc_name, expr_vec): + s = super(ChipMethodAccessAST, self) + s.__init__(slicc, machine, mach_version, component) + + self.chip_ver_expr = chip_version + self.expr_vec = expr_vec + self.proc_name = proc_name + + def generate_access(self, var): + # generate code + paramTypes = [] + gcode = [] + for expr in self.expr_vec: + t,c = expr.generate() + paramTypes.append(t) + gcode.append(c) + + methodId = var.type.methodId(self.proc_name, paramTypes) + + # Verify that this is a method of the object + if not var.type.methodExist(methodId): + error("%s: Type '%s' does not have a method '%s'" % \ + ("Invalid method call", var.type, methodId)) + + expected_size = len(var.type.methodParamType(methodId)) + if len(self.expr_vec) != expected_size: + # Right number of parameters + self.error("Wrong number of parameters for function name: " +\ + "'%s', expected: %d, actual: %d", + self.proc_name, expected_size, len(self.expr_vec)) + + for expr,expected,actual in zip(self.expr_vec, + var.type.methodParamType(methodId), + paramTypes): + # Check the types of the parameter + if actual != expected: + expr.error("Type mismatch: expected: %s actual: %s", + expected, actual) + + # method call + code = ".%s(%s)" % (self.proc_name, ', '.join(gcode)) + + # Return the return type of the method + return var.type.methodReturnType(methodId), code + +class LocalChipMethodAST(ChipMethodAccessAST): + # method call from local chip + def __init__(self, slicc, machine, mach_version, component, proc_name, + expr_vec): + s = super(LocalChipMethodAST, self) + s.__init__(slicc, None, machine, mach_version, component, proc_name, + expr_vec) + +class SpecifiedChipMethodAST(ChipMethodAccessAST): + # method call from specified chip + def __init__(self, slicc, chip_version, machine, mach_version, component, + proc_name, expr_vec): + s = super(SpecifiedChipMethodAST, self) + s.__init__(slicc, chip_version, machine, mach_version, component, + proc_name, expr_vec) + +class ChipMemberAccessAST(ChipComponentAccessAST): + # member access from specified chip + def __init__(self, chip_version, machine, mach_version, component, + field_name): + s = super(ChipMemberAccessAST, self) + s.__init__(slicc, machine, mach_version, component) + + self.chip_ver_expr = chip_version + self.field_name = field_name + + def generate_access(self, var): + # Verify that this is a valid field name for this type + if not var.type.dataMemberExist(self.field_name): + self.error("Invalid object field: " +\ + "Type '%s' does not have data member %s", + var.type, self.field_name) + + code += ").m_%s" % self.field_name + + return var.type.dataMemberType(self.field_name), code + +class LocalChipMemberAST(ChipMemberAccessAST): + # member access from local chip + def __init__(self, slicc, machine, mach_version, component, field_name): + s = super(LocalChipMemberAST, self) + s.__init__(slicc, None, machine, mach_version, component, field_name) + +class SpecifiedChipMemberAST(ChipMemberAccessAST): + # member access from specified chip + def __init__(self, chip_version, machine, mach_version, component, + field_name): + s = super(SpecifiedChipMemberAST, self) + s.__init__(slicc, chip_version, machine, mach_version, component, + field_name) diff --git a/src/mem/slicc/ast/CopyHeadStatementAST.cc b/src/mem/slicc/ast/CopyHeadStatementAST.cc deleted file mode 100644 index 8d455eb9df..0000000000 --- a/src/mem/slicc/ast/CopyHeadStatementAST.cc +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/ast/CopyHeadStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/gems_common/util.hh" - -CopyHeadStatementAST::CopyHeadStatementAST(VarExprAST* in_queue_ptr, - VarExprAST* out_queue_ptr, - PairListAST* pairs_ptr) - : StatementAST(pairs_ptr->getPairs()) -{ - m_in_queue_ptr = in_queue_ptr; - m_out_queue_ptr = out_queue_ptr; -} - -CopyHeadStatementAST::~CopyHeadStatementAST() -{ - delete m_in_queue_ptr; - delete m_out_queue_ptr; -} - -void CopyHeadStatementAST::generate(string& code, Type* return_type_ptr) const -{ - m_in_queue_ptr->assertType("InPort"); - m_out_queue_ptr->assertType("OutPort"); - - code += indent_str(); - code += m_out_queue_ptr->getVar()->getCode() + ".enqueue(" + m_in_queue_ptr->getVar()->getCode() + ".getMsgPtrCopy()"; - - if (getPairs().exist("latency")) { - code += ", " + getPairs().lookup("latency"); - } else { - code += ", COPY_HEAD_LATENCY"; - } - - code += ");\n"; -} - -void CopyHeadStatementAST::findResources(Map& resource_list) const -{ - Var* var_ptr = m_out_queue_ptr->getVar(); - int res_count = 0; - if (resource_list.exist(var_ptr)) { - res_count = atoi((resource_list.lookup(var_ptr)).c_str()); - } - resource_list.add(var_ptr, int_to_string(res_count+1)); -} - -void CopyHeadStatementAST::print(ostream& out) const -{ - out << "[CopyHeadStatementAst: " << *m_in_queue_ptr << " " << *m_out_queue_ptr << "]"; -} diff --git a/src/mem/slicc/ast/CopyHeadStatementAST.hh b/src/mem/slicc/ast/CopyHeadStatementAST.hh deleted file mode 100644 index 53d479136a..0000000000 --- a/src/mem/slicc/ast/CopyHeadStatementAST.hh +++ /dev/null @@ -1,87 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#ifndef COPYHEADSTATEMENTAST_H -#define COPYHEADTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/PairListAST.hh" - -class VarExprAST; -class Var; - -class CopyHeadStatementAST : public StatementAST { -public: - // Constructors - CopyHeadStatementAST(VarExprAST* in_queue_ptr, - VarExprAST* out_queue_ptr, - PairListAST* pairs_ptr); - - // Destructor - ~CopyHeadStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - CopyHeadStatementAST(const CopyHeadStatementAST& obj); - CopyHeadStatementAST& operator=(const CopyHeadStatementAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_in_queue_ptr; - VarExprAST* m_out_queue_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const CopyHeadStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const CopyHeadStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //COPYHEADSTATEMENTAST_H diff --git a/src/mem/slicc/ast/CopyHeadStatementAST.py b/src/mem/slicc/ast/CopyHeadStatementAST.py new file mode 100644 index 0000000000..ba99709753 --- /dev/null +++ b/src/mem/slicc/ast/CopyHeadStatementAST.py @@ -0,0 +1,52 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST + +class CopyHeadStatementAST(StatementAST): + def __init__(self, slicc, in_queue, out_queue, pairs): + super(CopyHeadStatementAST, self).__init__(slicc, pairs) + + self.in_queue = in_queue + self.out_queue_ptr = out_queue + + def __repr__(self): + return "[CopyHeadStatementAst: %r %r]" % (self.in_queue, + self.out_queue) + + def generate(self, code, return_type): + self.in_queue.assertType("InPort") + self.out_queue.assertType("OutPort") + + out_code = self.out_queue.var.code + in_code = self.in_queue.var.code + latency = self.get("latency", "COPY_HEAD_LATENCY") + code("$out_code.enqueue($in_code.getMsgPtrCopy(), $latency);") + + def findResources(self, resources): + var = self.out_queue.var + resources[var] = str(int(resources.get(var, "0")) + 1) diff --git a/src/mem/slicc/ast/DeclAST.cc b/src/mem/slicc/ast/DeclAST.cc deleted file mode 100644 index 6ccf9a9d61..0000000000 --- a/src/mem/slicc/ast/DeclAST.cc +++ /dev/null @@ -1,39 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * DeclAST.C - * - * Description: See DeclAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/DeclAST.hh" diff --git a/src/mem/slicc/ast/DeclAST.hh b/src/mem/slicc/ast/DeclAST.hh deleted file mode 100644 index d9e4555b42..0000000000 --- a/src/mem/slicc/ast/DeclAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * DeclAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef DECLAST_H -#define DECLAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" -#include "mem/slicc/ast/PairListAST.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class DeclAST : public AST { -public: - // Constructors - DeclAST(PairListAST* pairs_ptr) : AST(pairs_ptr->getPairs()) {} - - // Destructor - virtual ~DeclAST() {} - - // Public Methods - virtual void generate() = 0; - virtual void findMachines() {}; - - // void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - // DeclAST(const DeclAST& obj); - // DeclAST& operator=(const DeclAST& obj); - - // Data Members (m_ prefix) -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const DeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const DeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //DECLAST_H diff --git a/src/mem/slicc/ast/DeclAST.py b/src/mem/slicc/ast/DeclAST.py new file mode 100644 index 0000000000..2303725a39 --- /dev/null +++ b/src/mem/slicc/ast/DeclAST.py @@ -0,0 +1,38 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class DeclAST(AST): + def __init__(self, slicc, pairs): + super(DeclAST, self).__init__(slicc, pairs) + + def files(self, hh, cc, parent=None): + pass + + def findMachines(self): + return diff --git a/src/mem/slicc/ast/DeclListAST.cc b/src/mem/slicc/ast/DeclListAST.cc deleted file mode 100644 index 8337d714b4..0000000000 --- a/src/mem/slicc/ast/DeclListAST.cc +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * DeclListAST.C - * - * Description: See DeclListAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/DeclListAST.hh" - -DeclListAST::DeclListAST(Vector* vec_ptr) - : AST() -{ - assert(vec_ptr != NULL); - m_vec_ptr = vec_ptr; -} - -// Singleton constructor. -DeclListAST::DeclListAST(DeclAST* Decl_ptr) - : AST() -{ - assert(Decl_ptr != NULL); - m_vec_ptr = new Vector; - m_vec_ptr->insertAtTop(Decl_ptr); -} - -DeclListAST::~DeclListAST() -{ - int size = m_vec_ptr->size(); - for(int i=0; isize(); - for(int i=0; igenerate(); - } -} - -void DeclListAST::findMachines() const -{ - int size = m_vec_ptr->size(); - for(int i=0; ifindMachines(); - } -} - -void DeclListAST::print(ostream& out) const -{ - assert(m_vec_ptr != NULL); - out << "[DeclListAST: " << *m_vec_ptr << "]"; -} diff --git a/src/mem/slicc/ast/DeclListAST.hh b/src/mem/slicc/ast/DeclListAST.hh deleted file mode 100644 index 1c2bc3c05b..0000000000 --- a/src/mem/slicc/ast/DeclListAST.hh +++ /dev/null @@ -1,84 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * DeclListAST.hh - * - * Description: - * - * $Id: DeclListAST.hh,v 3.1 2001/12/12 01:00:12 milo Exp $ - * - */ - -#ifndef DeclListAST_H -#define DeclListAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" -#include "mem/slicc/ast/DeclAST.hh" - -class DeclListAST : public AST { -public: - // Constructors - DeclListAST(Vector* vec_ptr); - DeclListAST(DeclAST* statement_ptr); - - // Destructor - ~DeclListAST(); - - // Public Methods - void generate() const; - void findMachines() const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - DeclListAST(const DeclListAST& obj); - DeclListAST& operator=(const DeclListAST& obj); - - // Data Members (m_ prefix) - Vector* m_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const DeclListAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const DeclListAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //DeclListAST_H diff --git a/src/mem/slicc/ast/DeclListAST.py b/src/mem/slicc/ast/DeclListAST.py new file mode 100644 index 0000000000..42f98afc74 --- /dev/null +++ b/src/mem/slicc/ast/DeclListAST.py @@ -0,0 +1,51 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class DeclListAST(AST): + def __init__(self, slicc, decls): + super(DeclListAST, self).__init__(slicc) + + if not isinstance(decls, (list, tuple)): + decls = [ decls ] + self.decls = decls + + def __repr__(self): + return "[DeclListAST: %s]" % (', '.join(repr(d) for d in self.decls)) + + def files(self, hh, cc, parent=None): + for decl in self.decls: + decl.files(hh, cc, parent) + + def generate(self): + for decl in self.decls: + decl.generate() + + def findMachines(self): + for decl in self.decls: + decl.findMachines() diff --git a/src/mem/slicc/ast/EnqueueStatementAST.cc b/src/mem/slicc/ast/EnqueueStatementAST.cc deleted file mode 100644 index a422d8a280..0000000000 --- a/src/mem/slicc/ast/EnqueueStatementAST.cc +++ /dev/null @@ -1,111 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/ast/EnqueueStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/PairListAST.hh" -#include "mem/gems_common/util.hh" - -EnqueueStatementAST::EnqueueStatementAST(VarExprAST* queue_name_ptr, - TypeAST* type_name_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ast_ptr) - : StatementAST(pairs_ptr->getPairs()) -{ - m_queue_name_ptr = queue_name_ptr; - m_type_name_ptr = type_name_ptr; - m_statement_list_ast_ptr = statement_list_ast_ptr; -} - -EnqueueStatementAST::~EnqueueStatementAST() -{ - delete m_queue_name_ptr; - delete m_type_name_ptr; - delete m_statement_list_ast_ptr; -} - -void EnqueueStatementAST::generate(string& code, Type* return_type_ptr) const -{ - code += indent_str() + "{\n"; // Start scope - inc_indent(); - g_sym_table.pushFrame(); - - Type* msg_type_ptr = m_type_name_ptr->lookupType(); - - // Add new local var to symbol table - g_sym_table.newSym(new Var("out_msg", getLocation(), msg_type_ptr, "out_msg", getPairs())); - - code += indent_str() + msg_type_ptr->cIdent() + " out_msg;\n"; // Declare message - m_statement_list_ast_ptr->generate(code, NULL); // The other statements - - code += indent_str(); - - m_queue_name_ptr->assertType("OutPort"); - code += "(" + m_queue_name_ptr->getVar()->getCode() + ")"; - code += ".enqueue(out_msg"; - - if (getPairs().exist("latency")) { - bool is_number = true; - string val = getPairs().lookup("latency"); - for (int i=0; i& resource_list) const -{ - Var* var_ptr = m_queue_name_ptr->getVar(); - int res_count = 0; - if (resource_list.exist(var_ptr)) { - res_count = atoi((resource_list.lookup(var_ptr)).c_str()); - } - resource_list.add(var_ptr, int_to_string(res_count+1)); -} - -void EnqueueStatementAST::print(ostream& out) const -{ - out << "[EnqueueStatementAst: " << *m_queue_name_ptr << " " - << m_type_name_ptr->toString() << " " << *m_statement_list_ast_ptr << "]"; -} diff --git a/src/mem/slicc/ast/EnqueueStatementAST.hh b/src/mem/slicc/ast/EnqueueStatementAST.hh deleted file mode 100644 index fc2776ed70..0000000000 --- a/src/mem/slicc/ast/EnqueueStatementAST.hh +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnqueueStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef ENQUEUESTATEMENTAST_H -#define ENQUEUESTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class VarExprAST; -class Var; -class PairListAST; - -class EnqueueStatementAST : public StatementAST { -public: - // Constructors - EnqueueStatementAST(VarExprAST* queue_name_ptr, - TypeAST* type_name_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ast_ptr); - - // Destructor - ~EnqueueStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - EnqueueStatementAST(const EnqueueStatementAST& obj); - EnqueueStatementAST& operator=(const EnqueueStatementAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_queue_name_ptr; - TypeAST* m_type_name_ptr; - StatementListAST* m_statement_list_ast_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const EnqueueStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const EnqueueStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ENQUEUESTATEMENTAST_H diff --git a/src/mem/slicc/ast/EnqueueStatementAST.py b/src/mem/slicc/ast/EnqueueStatementAST.py new file mode 100644 index 0000000000..faf9664602 --- /dev/null +++ b/src/mem/slicc/ast/EnqueueStatementAST.py @@ -0,0 +1,86 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST +from slicc.symbols import Var + +class EnqueueStatementAST(StatementAST): + def __init__(self, slicc, queue_name, type_ast, pairs, statements): + super(EnqueueStatementAST, self).__init__(slicc, pairs) + + self.queue_name = queue_name + self.type_ast = type_ast + self.statements = statements + + def __repr__(self): + return "[EnqueueStatementAst: %s %s %s]" % \ + (self.queue_name, self.type_ast.ident, self.statements) + + def generate(self, code, return_type): + code("{") + code.indent() + self.symtab.pushFrame() + + msg_type = self.type_ast.type + + # Add new local var to symbol table + v = Var(self.symtab, "out_msg", self.location, msg_type, "out_msg", + self.pairs) + self.symtab.newSymbol(v) + + # Declare message + code("${{msg_type.ident}} out_msg;") + + # The other statements + t = self.statements.generate(code, None) + + self.queue_name.assertType("OutPort") + + args = [ "out_msg" ] + if "latency" in self: + latency = self["latency"] + try: + # see if this is an integer + latency = int(latency) + args.append("%s" % latency) + except ValueError: + # if not, it should be a member + args.append("m_%s" % latency) + + args = ", ".join(args) + code('(${{self.queue_name.var.code}}).enqueue($args);') + + + # End scope + self.symtab.popFrame() + code.dedent() + code("}") + + def findResources(self, resources): + var = self.queue_name.var + res_count = int(resources.get(var, 0)) + resources[var] = str(res_count + 1) diff --git a/src/mem/slicc/ast/EnumDeclAST.cc b/src/mem/slicc/ast/EnumDeclAST.cc deleted file mode 100644 index b051f3c8f5..0000000000 --- a/src/mem/slicc/ast/EnumDeclAST.cc +++ /dev/null @@ -1,98 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnumDeclAST.C - * - * Description: See EnumDeclAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/EnumDeclAST.hh" -#include "mem/slicc/main.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -EnumDeclAST::EnumDeclAST(TypeAST* type_ast_ptr, - PairListAST* pairs_ptr, - Vector* field_vec_ptr) - : DeclAST(pairs_ptr) -{ - m_type_ast_ptr = type_ast_ptr; - m_field_vec_ptr = field_vec_ptr; -} - -EnumDeclAST::~EnumDeclAST() -{ - delete m_type_ast_ptr; - if (m_field_vec_ptr != NULL) { - int size = m_field_vec_ptr->size(); - for(int i=0; itoString(); - - Vector param_type_vec; // used by to_string func call - - // Make the new type - Type* new_type_ptr = new Type(id, getLocation(), getPairs(), - g_sym_table.getStateMachine()); - g_sym_table.newSym(new_type_ptr); - - // Add all of the fields of the type to it - if (m_field_vec_ptr != NULL) { - int size = m_field_vec_ptr->size(); - for(int i=0; igenerate(new_type_ptr); - } - } - - // Add the implicit State_to_string method - FIXME, this is a bit dirty - param_type_vec.insertAtBottom(new_type_ptr); // add state to param vector - string func_id = new_type_ptr->cIdent()+"_to_string"; - - Map pairs; - pairs.add("external", "yes"); - Vector string_vec; - g_sym_table.newSym(new Func(func_id, getLocation(), g_sym_table.getType("string"), param_type_vec, string_vec, string(""), pairs, NULL)); -} - -void EnumDeclAST::print(ostream& out) const -{ - out << "[EnumDecl: " << m_type_ast_ptr->toString() << "]"; -} - diff --git a/src/mem/slicc/ast/EnumDeclAST.hh b/src/mem/slicc/ast/EnumDeclAST.hh deleted file mode 100644 index 2af650e833..0000000000 --- a/src/mem/slicc/ast/EnumDeclAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnummDeclAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef EnumDeclAST_H -#define EnumDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" - -class EnumDeclAST : public DeclAST { -public: - // Constructors - EnumDeclAST(TypeAST* type_ast_ptr, - PairListAST* pairs_ptr, - Vector* field_vec_ptr); - - // Destructor - ~EnumDeclAST(); - - // Public Methods - virtual void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - EnumDeclAST(const EnumDeclAST& obj); - EnumDeclAST& operator=(const EnumDeclAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_type_ast_ptr; - Vector* m_field_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const EnumDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const EnumDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //EnumDeclAST_H diff --git a/src/mem/slicc/ast/EnumDeclAST.py b/src/mem/slicc/ast/EnumDeclAST.py new file mode 100644 index 0000000000..c16fc8a750 --- /dev/null +++ b/src/mem/slicc/ast/EnumDeclAST.py @@ -0,0 +1,71 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Func, Type + +class EnumDeclAST(DeclAST): + def __init__(self, slicc, type_ast, pairs, fields): + super(EnumDeclAST, self).__init__(slicc, pairs) + + self.type_ast = type_ast + self.fields = fields + + def __repr__(self): + return "[EnumDecl: %s]" % (self.type_ast) + + def files(self, hh, cc, parent=None): + if "external" in self: + return + + if parent: + ident = "%s_%s" % (parent, self.type_ast.ident) + else: + ident = self.type_ast.ident + hh.add("%s.hh" % ident) + cc.add("%s.cc" % ident) + + def generate(self): + ident = str(self.type_ast) + + # Make the new type + t = Type(self.symtab, ident, self.location, self.pairs, + self.state_machine) + self.symtab.newSymbol(t) + + # Add all of the fields of the type to it + for field in self.fields: + field.generate(t) + + # Add the implicit State_to_string method - FIXME, this is a bit dirty + func_id = "%s_to_string" % t.c_ident + + pairs = { "external" : "yes" } + func = Func(self.symtab, func_id, self.location, + self.symtab.find("string", Type), [ t ], [], "", + pairs, None) + self.symtab.newSymbol(func) diff --git a/src/mem/slicc/ast/EnumExprAST.cc b/src/mem/slicc/ast/EnumExprAST.cc deleted file mode 100644 index 0d8af0e9f2..0000000000 --- a/src/mem/slicc/ast/EnumExprAST.cc +++ /dev/null @@ -1,76 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnumExprAST.C - * - * Description: See EnumExprAST.hh - * - * $Id: EnumExprAST.C,v 3.1 2003/07/10 18:08:06 milo Exp $ - * - */ - -#include "mem/slicc/ast/EnumExprAST.hh" - -EnumExprAST::EnumExprAST(TypeAST* type_ast_ptr, - string* value_ptr) - : ExprAST() -{ - assert(value_ptr != NULL); - assert(type_ast_ptr != NULL); - m_type_ast_ptr = type_ast_ptr; - m_value_ptr = value_ptr; -} - -EnumExprAST::~EnumExprAST() -{ - delete m_type_ast_ptr; - delete m_value_ptr; -} - -Type* EnumExprAST::generate(string& code) const -{ - Type* type_ptr = m_type_ast_ptr->lookupType(); - code += type_ptr->cIdent() + "_" + (*m_value_ptr); - - // Make sure the enumeration value exists - if (!type_ptr->enumExist(*m_value_ptr)) { - error("Type '" + m_type_ast_ptr->toString() + "' does not have enumeration '" + *m_value_ptr + "'"); - } - - // Return the proper type - return type_ptr; -} - -void EnumExprAST::print(ostream& out) const -{ - string str; - str += m_type_ast_ptr->toString()+":"+(*m_value_ptr); - out << "[EnumExpr: " << str << "]"; -} diff --git a/src/mem/slicc/ast/EnumExprAST.hh b/src/mem/slicc/ast/EnumExprAST.hh deleted file mode 100644 index 8af1c88917..0000000000 --- a/src/mem/slicc/ast/EnumExprAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * EnumExprAST.hh - * - * Description: - * - * $Id: EnumExprAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef EnumExprAST_H -#define EnumExprAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - - -class EnumExprAST : public ExprAST { -public: - // Constructors - EnumExprAST(TypeAST* type_ast_ptr, - string* value_ptr); - - // Destructor - ~EnumExprAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - EnumExprAST(const EnumExprAST& obj); - EnumExprAST& operator=(const EnumExprAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_type_ast_ptr; - string* m_value_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const EnumExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const EnumExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //EnumExprAST_H diff --git a/src/mem/slicc/ast/EnumExprAST.py b/src/mem/slicc/ast/EnumExprAST.py new file mode 100644 index 0000000000..9cb76a8a19 --- /dev/null +++ b/src/mem/slicc/ast/EnumExprAST.py @@ -0,0 +1,53 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST + +class EnumExprAST(ExprAST): + def __init__(self, slicc, type_ast, value): + super(EnumExprAST, self).__init__(slicc) + + assert type_ast + assert value + + self.type_ast = type_ast + self.value = value + + def __repr__(self): + return "[EnumExpr: %s:%s]" % (self.type_ast, self.value) + + def generate(self, code): + fix = code.nofix() + code('${{self.type_ast.type.c_ident}}_${{self.value}}') + code.fix(fix) + + # Make sure the enumeration value exists + if self.value not in self.type_ast.type.enums: + self.error("Type '%s' does not have enumeration '%s'", + self.type_ast, self.value) + + return self.type_ast.type diff --git a/src/mem/slicc/ast/ExprAST.cc b/src/mem/slicc/ast/ExprAST.cc deleted file mode 100644 index 3427d4dd95..0000000000 --- a/src/mem/slicc/ast/ExprAST.cc +++ /dev/null @@ -1,39 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ExprAST.C - * - * Description: See ExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/ExprAST.hh" diff --git a/src/mem/slicc/ast/ExprAST.hh b/src/mem/slicc/ast/ExprAST.hh deleted file mode 100644 index 9566541dac..0000000000 --- a/src/mem/slicc/ast/ExprAST.hh +++ /dev/null @@ -1,84 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ExprAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef EXPRAST_H -#define EXPRAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" - - -class ExprAST : public AST { -public: - // Constructors - ExprAST() : AST() { } - - // Destructor - virtual ~ExprAST() { } - - // Public Methods - virtual Type* generate(string& code) const = 0; - virtual void findResources(Map& resource_list) const {} // The default is no resources - - // void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - // ExprAST(const ExprAST& obj); - // ExprAST& operator=(const ExprAST& obj); - - // Data Members (m_ prefix) - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //EXPRAST_H diff --git a/src/mem/slicc/ast/ExprAST.py b/src/mem/slicc/ast/ExprAST.py new file mode 100644 index 0000000000..70a0aa0b59 --- /dev/null +++ b/src/mem/slicc/ast/ExprAST.py @@ -0,0 +1,45 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.AST import AST + +class ExprAST(AST): + def __init__(self, slicc): + super(ExprAST, self).__init__(slicc) + + def findResources(self, resources): + # The default is no resources + pass + + def inline(self, get_type=False): + code = code_formatter(fix_newlines=False) + return_type = self.generate(code) + if get_type: + return return_type, code + else: + return code diff --git a/src/mem/slicc/ast/ExprStatementAST.cc b/src/mem/slicc/ast/ExprStatementAST.cc deleted file mode 100644 index f4bffaab37..0000000000 --- a/src/mem/slicc/ast/ExprStatementAST.cc +++ /dev/null @@ -1,73 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ExprStatementAST.C - * - * Description: See ExprStatementAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/ExprStatementAST.hh" - -ExprStatementAST::ExprStatementAST(ExprAST* expr_ptr) - : StatementAST() -{ - m_expr_ptr = expr_ptr; -} - -ExprStatementAST::~ExprStatementAST() -{ - delete m_expr_ptr; -} - -void ExprStatementAST::generate(string& code, Type* return_type_ptr) const -{ - code += indent_str(); - Type* actual_type_ptr = m_expr_ptr->generate(code); - code += ";\n"; - - // The return type must be void - Type* expected_type_ptr = g_sym_table.getType("void"); - if (expected_type_ptr != actual_type_ptr) { - m_expr_ptr->error("Non-void return must not be ignored, return type is '" + actual_type_ptr->toString() + "'"); - } -} - -void ExprStatementAST::findResources(Map& resource_list) const -{ - m_expr_ptr->findResources(resource_list); -} - -void ExprStatementAST::print(ostream& out) const -{ - out << "[ExprStatementAST: " << *m_expr_ptr << "]"; -} diff --git a/src/mem/slicc/ast/ExprStatementAST.hh b/src/mem/slicc/ast/ExprStatementAST.hh deleted file mode 100644 index a47e86af5e..0000000000 --- a/src/mem/slicc/ast/ExprStatementAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ExprStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef ExprStatementAST_H -#define ExprStatementAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - -class ExprStatementAST : public StatementAST { -public: - // Constructors - ExprStatementAST(ExprAST* expr_ptr); - - // Destructor - ~ExprStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ExprStatementAST(const ExprStatementAST& obj); - ExprStatementAST& operator=(const ExprStatementAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_expr_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ExprStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ExprStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ExprStatementAST_H diff --git a/src/mem/slicc/ast/ExprStatementAST.py b/src/mem/slicc/ast/ExprStatementAST.py new file mode 100644 index 0000000000..b16d1d0729 --- /dev/null +++ b/src/mem/slicc/ast/ExprStatementAST.py @@ -0,0 +1,52 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.StatementAST import StatementAST +from slicc.symbols import Type + +class ExprStatementAST(StatementAST): + def __init__(self, slicc, expr): + super(ExprStatementAST, self).__init__(slicc) + self.expr = expr + + def __repr__(self): + return "[ExprStatementAST: %s]" % (self.expr) + + def generate(self, code, return_type): + actual_type,rcode = self.expr.inline(True) + code("$rcode;") + + # The return type must be void + if actual_type != self.symtab.find("void", Type): + self.expr.error("Non-void return must not be ignored, " + \ + "return type is '%s'", actual_type.ident) + + def findResources(self, resources): + self.expr.findResources(resources) + diff --git a/src/mem/slicc/ast/FormalParamAST.cc b/src/mem/slicc/ast/FormalParamAST.cc deleted file mode 100644 index 529811f259..0000000000 --- a/src/mem/slicc/ast/FormalParamAST.cc +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FormalParamAST.C - * - * Description: See FormalParamAST.hh - * - * $Id: FormalParamAST.C,v 3.1 2000/10/05 21:22:20 milo Exp $ - * - */ - -#include "mem/slicc/ast/FormalParamAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -FormalParamAST::~FormalParamAST() -{ - delete m_ident_ptr; - delete m_type_ast_ptr; -} - -string FormalParamAST::getTypeName() const -{ - return m_type_ast_ptr->toString(); -} - -Type* FormalParamAST::getType() const -{ - return m_type_ast_ptr->lookupType(); -} - -Type* FormalParamAST::generate(string& code) const -{ - string param = "param_" + *m_ident_ptr; - - Type* type_ptr = m_type_ast_ptr->lookupType(); - code += type_ptr->cIdent(); - code += " "; - code += param; - - // Add to symbol table - g_sym_table.newSym(new Var(*m_ident_ptr, getLocation(), type_ptr, param, getPairs())); - return type_ptr; -} diff --git a/src/mem/slicc/ast/FormalParamAST.hh b/src/mem/slicc/ast/FormalParamAST.hh deleted file mode 100644 index ca27948b7a..0000000000 --- a/src/mem/slicc/ast/FormalParamAST.hh +++ /dev/null @@ -1,88 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FormalParamAST.hh - * - * Description: - * - * $Id: FormalParamAST.hh,v 3.1 2001/12/12 01:00:15 milo Exp $ - * - */ - -#ifndef FORMALPARAMAST_H -#define FORMALPARAMAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" - -class TypeAST; - - -class FormalParamAST : public AST { -public: - // Constructors - FormalParamAST(TypeAST* type_ast_ptr, string* ident_ptr) : AST() { m_type_ast_ptr = type_ast_ptr; m_ident_ptr = ident_ptr; } - - // Destructor - ~FormalParamAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const { out << "[FormalParamAST: " << *m_ident_ptr << "]"; } - string getName() const { return *m_ident_ptr; } - string getTypeName() const; - Type* getType() const; -private: - // Private Methods - - // Private copy constructor and assignment operator - FormalParamAST(const FormalParamAST& obj); - FormalParamAST& operator=(const FormalParamAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_type_ast_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const FormalParamAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const FormalParamAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //FORMALPARAMAST_H diff --git a/src/mem/slicc/ast/FormalParamAST.py b/src/mem/slicc/ast/FormalParamAST.py new file mode 100644 index 0000000000..b169cbb1c1 --- /dev/null +++ b/src/mem/slicc/ast/FormalParamAST.py @@ -0,0 +1,52 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST +from slicc.symbols import Var + +class FormalParamAST(AST): + def __init__(self, slicc, type_ast, ident): + super(FormalParamAST, self).__init__(slicc) + self.type_ast = type_ast + self.ident = ident + + def __repr__(self): + return "[FormalParamAST: %s]" % self.ident + + @property + def name(self): + return self.ident + + def generate(self): + type = self.type_ast.type + param = "param_%s" % self.ident + + # Add to symbol table + v = Var(self.symtab, self.ident, self.location, type, param, + self.pairs) + self.symtab.newSymbol(v) + return type, "%s %s" % (type.c_ident, param) diff --git a/src/mem/slicc/ast/FuncCallExprAST.cc b/src/mem/slicc/ast/FuncCallExprAST.cc deleted file mode 100644 index 5b19017e96..0000000000 --- a/src/mem/slicc/ast/FuncCallExprAST.cc +++ /dev/null @@ -1,224 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FuncCallExprAST.C - * - * Description: See FuncCallExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/FuncCallExprAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -FuncCallExprAST::FuncCallExprAST(string* proc_name_ptr, - Vector* expr_vec_ptr) - : ExprAST() -{ - m_proc_name_ptr = proc_name_ptr; - m_expr_vec_ptr = expr_vec_ptr; -} - -FuncCallExprAST::~FuncCallExprAST() -{ - delete m_proc_name_ptr; - int size = m_expr_vec_ptr->size(); - for(int i=0; igetLocation().toString(); - code += ": \", "; - (*m_expr_vec_ptr)[0]->generate(code); - code += ");\n"; - Type* void_type_ptr = g_sym_table.getType("void"); - assert(void_type_ptr != NULL); - return void_type_ptr; - } - - // hack for adding comments to profileTransition - if (*m_proc_name_ptr == "APPEND_TRANSITION_COMMENT") { - // FIXME - check for number of parameters - code += "APPEND_TRANSITION_COMMENT("; - //code += (*m_expr_vec_ptr)[0]->getLocation().toString(); - //code += ": \", "; - (*m_expr_vec_ptr)[0]->generate(code); - code += ");\n"; - Type* void_type_ptr = g_sym_table.getType("void"); - assert(void_type_ptr != NULL); - return void_type_ptr; - } - - // Look up the function in the symbol table - Vector code_vec; - Func* func_ptr = g_sym_table.getFunc(*m_proc_name_ptr); - - // Check the types and get the code for the parameters - if (func_ptr == NULL) { - error("Unrecognized function name: '" + *m_proc_name_ptr + "'"); - } else { - int size = m_expr_vec_ptr->size(); - - Vector f = func_ptr->getParamTypes(); - - if (size != f.size() ) { - error("Wrong number of arguments passed to function : '" + *m_proc_name_ptr + "'"); - } - else { - for(int i=0; igenerate(param_code); - Type* expected_type_ptr = func_ptr->getParamTypes()[i]; - if (actual_type_ptr != expected_type_ptr) { - (*m_expr_vec_ptr)[i]->error("Type mismatch: expected: " + expected_type_ptr->toString() + - " actual: " + actual_type_ptr->toString()); - } - code_vec.insertAtBottom(param_code); - } - } - } - - /* OK, the semantics of "trigger" here is that, ports in the machine have - * different priorities. We always check the first port for doable - * transitions. If nothing/stalled, we pick one from the next port. - * - * One thing we have to be careful as the SLICC protocol writter is : - * If a port have two or more transitions can be picked from in one cycle, - * they must be independent. Otherwise, if transition A and B mean to be - * executed in sequential, and A get stalled, transition B can be issued - * erroneously. In practice, in most case, there is only one transition - * should be executed in one cycle for a given port. So as most of current - * protocols. - */ - - if (*m_proc_name_ptr == "trigger") { - code += indent_str() + "{\n"; - code += indent_str() + " Address addr = "; - code += code_vec[1]; - code += ";\n"; - code += indent_str() + " TransitionResult result = doTransition("; - code += code_vec[0]; - code += ", " + g_sym_table.getStateMachine()->toString() + "_getState(addr), addr"; - if(CHECK_INVALID_RESOURCE_STALLS) { - // FIXME - the current assumption is that in_buffer_rank is declared in the msg buffer peek statement - code += ", in_buffer_rank"; - } - code += ");\n"; - code += indent_str() + " if (result == TransitionResult_Valid) {\n"; - code += indent_str() + " counter++;\n"; - code += indent_str() + " continue; // Check the first port again\n"; - code += indent_str() + " }\n"; - code += indent_str() + " if (result == TransitionResult_ResourceStall) {\n"; - code += indent_str() + " g_eventQueue_ptr->scheduleEvent(this, 1);\n"; - code += indent_str() + " // Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n"; - code += indent_str() + " }\n"; - code += indent_str() + "}\n"; - } else if (*m_proc_name_ptr == "doubleTrigger") { - // NOTE: Use the doubleTrigger call with extreme caution - // the key to double trigger is the second event triggered cannot fail becuase the first event cannot be undone - assert(code_vec.size() == 4); - code += indent_str() + "{\n"; - code += indent_str() + " Address addr1 = "; - code += code_vec[1]; - code += ";\n"; - code += indent_str() + " TransitionResult result1 = doTransition("; - code += code_vec[0]; - code += ", " + g_sym_table.getStateMachine()->toString() + "_getState(addr1), addr1"; - if(CHECK_INVALID_RESOURCE_STALLS) { - // FIXME - the current assumption is that in_buffer_rank is declared in the msg buffer peek statement - code += ", in_buffer_rank"; - } - code += ");\n"; - code += indent_str() + " if (result1 == TransitionResult_Valid) {\n"; - code += indent_str() + " //this second event cannont fail because the first event already took effect\n"; - code += indent_str() + " Address addr2 = "; - code += code_vec[3]; - code += ";\n"; - code += indent_str() + " TransitionResult result2 = doTransition("; - code += code_vec[2]; - code += ", " + g_sym_table.getStateMachine()->toString() + "_getState(addr2), addr2"; - if(CHECK_INVALID_RESOURCE_STALLS) { - // FIXME - the current assumption is that in_buffer_rank is declared in the msg buffer peek statement - code += ", in_buffer_rank"; - } - code += ");\n"; - code += indent_str() + " assert(result2 == TransitionResult_Valid); // ensure the event suceeded\n"; - code += indent_str() + " counter++;\n"; - code += indent_str() + " continue; // Check the first port again\n"; - code += indent_str() + " }\n"; - code += indent_str() + " if (result1 == TransitionResult_ResourceStall) {\n"; - code += indent_str() + " g_eventQueue_ptr->scheduleEvent(this, 1);\n"; - code += indent_str() + " // Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n"; - code += indent_str() + " }\n"; - code += indent_str() + "}\n"; - } else if (*m_proc_name_ptr == "error") { - code += indent_str() + (*m_expr_vec_ptr)[0]->embedError(code_vec[0]) + "\n"; - } else if (*m_proc_name_ptr == "assert") { - code += indent_str() + "if (ASSERT_FLAG && !(" + code_vec[0] + ")) {\n"; - code += indent_str() + " " + (*m_expr_vec_ptr)[0]->embedError("\"assert failure\"") + "\n"; - code += indent_str() + "}\n"; - } else if (*m_proc_name_ptr == "continueProcessing") { - code += "counter++; continue; // Check the first port again"; - } else { - // Normal function - code += "("; - // if the func is internal to the chip but not the machine then it can only be - // accessed through the chip pointer - if (!func_ptr->existPair("external") && !func_ptr->isInternalMachineFunc()) { - code += "m_chip_ptr->"; - } - code += func_ptr->cIdent() + "("; - int size = code_vec.size(); - for(int i=0; igetReturnType(); -} - -void FuncCallExprAST::print(ostream& out) const -{ - out << "[FuncCallExpr: " << *m_proc_name_ptr << " " << *m_expr_vec_ptr << "]"; -} diff --git a/src/mem/slicc/ast/FuncCallExprAST.hh b/src/mem/slicc/ast/FuncCallExprAST.hh deleted file mode 100644 index 6c02122ee0..0000000000 --- a/src/mem/slicc/ast/FuncCallExprAST.hh +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FuncCallExprAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef FUNCCALLEXPRAST_H -#define FUNCCALLEXPRAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - - -// ProcGen decl -class FuncGen; - -class FuncCallExprAST : public ExprAST { -public: - // Constructors - FuncCallExprAST(string* proc_name_ptr, - Vector* expr_vec_ptr); - - // Destructor - ~FuncCallExprAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const; - -private: - // Private Methods - - // Private copy constructor and assignment operator - FuncCallExprAST(const FuncCallExprAST& obj); - FuncCallExprAST& operator=(const FuncCallExprAST& obj); - - // Data Members (m_ prefix) - string* m_proc_name_ptr; - Vector* m_expr_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const FuncCallExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const FuncCallExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //FUNCCALLEXPRAST_H diff --git a/src/mem/slicc/ast/FuncCallExprAST.py b/src/mem/slicc/ast/FuncCallExprAST.py new file mode 100644 index 0000000000..abf7eec7b3 --- /dev/null +++ b/src/mem/slicc/ast/FuncCallExprAST.py @@ -0,0 +1,168 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Func, Type + +class FuncCallExprAST(ExprAST): + def __init__(self, slicc, proc_name, exprs): + super(FuncCallExprAST, self).__init__(slicc) + self.proc_name = proc_name + self.exprs = exprs + + def __repr__(self): + return "[FuncCallExpr: %s %s]" % (self.proc_name, self.exprs) + + def generate(self, code): + machine = self.state_machine + + # DEBUG_EXPR is strange since it takes parameters of multiple types + if self.proc_name == "DEBUG_EXPR": + # FIXME - check for number of parameters + code('DEBUG_SLICC(MedPrio, "$0: ", $1)', + self.exprs[0].location, self.exprs[0].inline()) + + return self.symtab.find("void", Type) + + # hack for adding comments to profileTransition + if self.proc_name == "APPEND_TRANSITION_COMMENT": + # FIXME - check for number of parameters + code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline()) + return self.symtab.find("void", Type) + + # Look up the function in the symbol table + func = self.symtab.find(self.proc_name, Func) + + # Check the types and get the code for the parameters + if func is None: + self.error("Unrecognized function name: '%s'", self.proc_name) + + if len(self.exprs) != len(func.param_types): + self.error("Wrong number of arguments passed to function : '%s'" +\ + " Expected %d, got %d", self.proc_name, + len(func.param_types), len(self.exprs)) + + cvec = [] + for expr,expected_type in zip(self.exprs, func.param_types): + # Check the types of the parameter + actual_type,param_code = expr.inline(True) + if actual_type != expected_type: + expr.error("Type mismatch: expected: %s actual: %s" % \ + (expected_type, actual_type)) + cvec.append(param_code) + + # OK, the semantics of "trigger" here is that, ports in the + # machine have different priorities. We always check the first + # port for doable transitions. If nothing/stalled, we pick one + # from the next port. + # + # One thing we have to be careful as the SLICC protocol + # writter is : If a port have two or more transitions can be + # picked from in one cycle, they must be independent. + # Otherwise, if transition A and B mean to be executed in + # sequential, and A get stalled, transition B can be issued + # erroneously. In practice, in most case, there is only one + # transition should be executed in one cycle for a given + # port. So as most of current protocols. + + if self.proc_name == "trigger": + code(''' +{ + Address addr = ${{cvec[1]}}; + TransitionResult result = doTransition(${{cvec[0]}}, ${machine}_getState(addr), addr); + + if (result == TransitionResult_Valid) { + counter++; + continue; // Check the first port again + } + + if (result == TransitionResult_ResourceStall) { + g_eventQueue_ptr->scheduleEvent(this, 1); + + // Cannot do anything with this transition, go check next doable transition (mostly likely of next port) + } +} +''') + elif self.proc_name == "doubleTrigger": + # NOTE: Use the doubleTrigger call with extreme caution + # the key to double trigger is the second event triggered + # cannot fail becuase the first event cannot be undone + assert len(cvec) == 4 + code(''' +{ + Address addr1 = ${{cvec[1]}}; + TransitionResult result1 = + doTransition(${{cvec[0]}}, ${machine}_getState(addr1), addr1); + + if (result1 == TransitionResult_Valid) { + //this second event cannont fail because the first event + // already took effect + Address addr2 = ${{cvec[3]}}; + TransitionResult result2 = doTransition(${{cvec[2]}}, ${machine}_getState(addr2), addr2); + + // ensure the event suceeded + assert(result2 == TransitionResult_Valid); + + counter++; + continue; // Check the first port again + } + + if (result1 == TransitionResult_ResourceStall) { + g_eventQueue_ptr->scheduleEvent(this, 1); + // Cannot do anything with this transition, go check next + // doable transition (mostly likely of next port) + } +} +''') + elif self.proc_name == "error": + code("$0", self.exprs[0].embedError(cvec[0])) + elif self.proc_name == "assert": + error = self.exprs[0].embedError('"assert failure"') + code(''' +if (ASSERT_FLAG && !(${{cvec[0]}})) { + $error +} +''') + + elif self.proc_name == "continueProcessing": + code("counter++;") + code("continue; // Check the first port again") + else: + # Normal function + + # if the func is internal to the chip but not the machine + # then it can only be accessed through the chip pointer + internal = "" + if "external" not in func and not func.isInternalMachineFunc: + internal = "m_chip_ptr->" + + params = ', '.join(str(c) for c in cvec) + fix = code.nofix() + code('(${internal}${{func.c_ident}}($params))') + code.fix(fix) + + return func.return_type diff --git a/src/mem/slicc/ast/FuncDeclAST.cc b/src/mem/slicc/ast/FuncDeclAST.cc deleted file mode 100644 index 2a0905f06d..0000000000 --- a/src/mem/slicc/ast/FuncDeclAST.cc +++ /dev/null @@ -1,112 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FuncDeclAST.C - * - * Description: See FuncDeclAST.hh - * - * $Id: FuncDeclAST.C,v 3.4 2003/08/22 18:19:34 beckmann Exp $ - * - */ - -#include "mem/slicc/ast/FuncDeclAST.hh" -#include "mem/slicc/ast/FormalParamAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/main.hh" - -FuncDeclAST::FuncDeclAST(TypeAST* return_type_ast_ptr, - string* ident_ptr, - Vector* formal_vec_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr) - : DeclAST(pairs_ptr) -{ - m_return_type_ast_ptr = return_type_ast_ptr; - m_ident_ptr = ident_ptr; - m_formal_vec_ptr = formal_vec_ptr; - m_statement_list_ptr = statement_list_ptr; -} - -FuncDeclAST::~FuncDeclAST() -{ - delete m_return_type_ast_ptr; - delete m_ident_ptr; - - int size = m_formal_vec_ptr->size(); - for(int i=0; i type_vec; - Vector param_vec; - Type* void_type_ptr = g_sym_table.getType("void"); - - // Generate definition code - g_sym_table.pushFrame(); - - // Lookup return type - Type* return_type_ptr = m_return_type_ast_ptr->lookupType(); - - // Generate function header - int size = m_formal_vec_ptr->size(); - for(int i=0; igenerate(ident); - type_vec.insertAtBottom(type_ptr); - param_vec.insertAtBottom(ident); - } - - string body; - if (m_statement_list_ptr == NULL) { - getPairs().add("external", "yes"); - } else { - m_statement_list_ptr->generate(body, return_type_ptr); - } - g_sym_table.popFrame(); - - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr != NULL) { - machine_ptr->addFunc(new Func(*m_ident_ptr, getLocation(), return_type_ptr, type_vec, param_vec, body, getPairs(), machine_ptr)); - } else { - g_sym_table.newSym(new Func(*m_ident_ptr, getLocation(), return_type_ptr, type_vec, param_vec, body, getPairs(), machine_ptr)); - } - -} - -void FuncDeclAST::print(ostream& out) const -{ - out << "[FuncDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/FuncDeclAST.hh b/src/mem/slicc/ast/FuncDeclAST.hh deleted file mode 100644 index 205e71a85d..0000000000 --- a/src/mem/slicc/ast/FuncDeclAST.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FuncDeclAST.hh - * - * Description: - * - * $Id: FuncDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef FuncDeclAST_H -#define FuncDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class FormalParamsAST; - -class FuncDeclAST : public DeclAST { -public: - // Constructors - FuncDeclAST(TypeAST* return_type_ptr, - string* ident_ptr, - Vector* formal_vec_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr); - // Destructor - ~FuncDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - FuncDeclAST(const FuncDeclAST& obj); - FuncDeclAST& operator=(const FuncDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_return_type_ast_ptr; - Vector* m_formal_vec_ptr; - StatementListAST* m_statement_list_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const FuncDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const FuncDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //FuncDeclAST_H diff --git a/src/mem/slicc/ast/FuncDeclAST.py b/src/mem/slicc/ast/FuncDeclAST.py new file mode 100644 index 0000000000..7ff3bf8a77 --- /dev/null +++ b/src/mem/slicc/ast/FuncDeclAST.py @@ -0,0 +1,88 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util.code_formatter import code_formatter + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Func, Type + +class FuncDeclAST(DeclAST): + def __init__(self, slicc, return_type, ident, formals, pairs, statements): + super(FuncDeclAST, self).__init__(slicc, pairs) + + self.return_type = return_type + self.ident = ident + self.formals = formals + self.statements = statements + + def __repr__(self): + return "[FuncDecl: %s]" % self.ident + + def files(self, hh, cc, parent=None): + if "external" in self or self.statements is None: + return + + if parent: + ident = "%s_%s" % (parent, self.ident) + else: + ident = self.ident + cc.add("%s.cc" % ident) + + def generate(self): + types = [] + params = [] + void_type = self.symtab.find("void", Type) + + # Generate definition code + self.symtab.pushFrame() + + # Lookup return type + return_type = self.return_type.type + + # Generate function header + for formal in self.formals: + # Lookup parameter types + type, ident = formal.generate() + types.append(type) + params.append(ident) + + body = code_formatter() + if self.statements is None: + self["external"] = "yes" + else: + rtype = self.statements.generate(body, return_type) + + self.symtab.popFrame() + + machine = self.state_machine + func = Func(self.symtab, self.ident, self.location, return_type, + types, params, str(body), self.pairs, machine) + + if machine is not None: + machine.addFunc(func) + else: + self.symtab.newSymbol(func) diff --git a/src/mem/slicc/ast/IfStatementAST.cc b/src/mem/slicc/ast/IfStatementAST.cc deleted file mode 100644 index 40942a58db..0000000000 --- a/src/mem/slicc/ast/IfStatementAST.cc +++ /dev/null @@ -1,98 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * IfStatementAST.C - * - * Description: See IfStatementAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/IfStatementAST.hh" - -IfStatementAST::IfStatementAST(ExprAST* cond_ptr, - StatementListAST* then_ptr, - StatementListAST* else_ptr) - : StatementAST() -{ - assert(cond_ptr != NULL); - assert(then_ptr != NULL); - m_cond_ptr = cond_ptr; - m_then_ptr = then_ptr; - m_else_ptr = else_ptr; -} - -IfStatementAST::~IfStatementAST() -{ - delete m_cond_ptr; - delete m_then_ptr; - delete m_else_ptr; -} - - -void IfStatementAST::generate(string& code, Type* return_type_ptr) const -{ - Type* type_ptr; - - // Conditional - code += indent_str() + "if ("; - type_ptr = m_cond_ptr->generate(code); - if (type_ptr != g_sym_table.getType("bool")) { - m_cond_ptr->error("Condition of if statement must be boolean, type was '" + type_ptr->toString() + "'"); - } - code += ") {\n"; - // Then part - inc_indent(); - m_then_ptr->generate(code, return_type_ptr); - dec_indent(); - // Else part - if (m_else_ptr != NULL) { - code += indent_str() + "} else {\n"; - inc_indent(); - m_else_ptr->generate(code, return_type_ptr); - dec_indent(); - } - code += indent_str() + "}\n"; // End scope -} - -void IfStatementAST::findResources(Map& resource_list) const -{ - // Take a worse case look at both paths - m_then_ptr->findResources(resource_list); - if (m_else_ptr != NULL) { - m_else_ptr->findResources(resource_list); - } -} - -void IfStatementAST::print(ostream& out) const -{ - out << "[IfStatement: " << *m_cond_ptr << *m_then_ptr << *m_else_ptr << "]"; -} diff --git a/src/mem/slicc/ast/IfStatementAST.hh b/src/mem/slicc/ast/IfStatementAST.hh deleted file mode 100644 index 2c168913a3..0000000000 --- a/src/mem/slicc/ast/IfStatementAST.hh +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * IfStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef IFSTATEMENTAST_H -#define IFSTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" - - -class IfStatementAST : public StatementAST { -public: - // Constructors - IfStatementAST(ExprAST* cond_ptr, - StatementListAST* then_ptr, - StatementListAST* else_ptr); - - // Destructor - ~IfStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - IfStatementAST(const IfStatementAST& obj); - IfStatementAST& operator=(const IfStatementAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_cond_ptr; - StatementListAST* m_then_ptr; - StatementListAST* m_else_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const IfStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const IfStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //IFSTATEMENTAST_H diff --git a/src/mem/slicc/ast/IfStatementAST.py b/src/mem/slicc/ast/IfStatementAST.py new file mode 100644 index 0000000000..788876fd11 --- /dev/null +++ b/src/mem/slicc/ast/IfStatementAST.py @@ -0,0 +1,74 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.StatementAST import StatementAST +from slicc.symbols import Type + +class IfStatementAST(StatementAST): + def __init__(self, slicc, cond, then, else_): + super(IfStatementAST, self).__init__(slicc) + + assert cond is not None + assert then is not None + + self.cond = cond + self.then = then + self.else_ = else_ + + def __repr__(self): + return "[IfStatement: %r%r%r]" % (self.cond, self.then, self.else_) + + def generate(self, code, return_type): + cond_code = code_formatter() + cond_type = self.cond.generate(cond_code) + + if cond_type != self.symtab.find("bool", Type): + self.cond.error("Condition of if stmt must be bool, type was '%s'", + ctype) + + # Conditional + code.indent() + code('if ($cond_code) {') + # Then part + code.indent() + self.then.generate(code, return_type) + code.dedent() + # Else part + if self.else_: + code('} else {') + code.indent() + self.else_.generate(code, return_type) + code.dedent() + code('}') # End scope + + def findResources(self, resources): + # Take a worse case look at both paths + self.then.findResources(resources) + if self.else_ is not None: + self.else_.findResources(resources) diff --git a/src/mem/slicc/ast/InPortDeclAST.cc b/src/mem/slicc/ast/InPortDeclAST.cc deleted file mode 100644 index f62af9921a..0000000000 --- a/src/mem/slicc/ast/InPortDeclAST.cc +++ /dev/null @@ -1,149 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InPortDeclAST.C - * - * Description: See InPortDeclAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/InPortDeclAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/symbols/Var.hh" - -InPortDeclAST::InPortDeclAST(string* ident_ptr, - TypeAST* msg_type_ptr, - ExprAST* var_expr_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr) - : DeclAST(pairs_ptr) -{ - m_ident_ptr = ident_ptr; - m_msg_type_ptr = msg_type_ptr; - m_var_expr_ptr = var_expr_ptr; - m_statement_list_ptr = statement_list_ptr; - m_queue_type_ptr = new TypeAST(new string("InPort")); -} - -InPortDeclAST::~InPortDeclAST() -{ - delete m_ident_ptr; - delete m_msg_type_ptr; - delete m_var_expr_ptr; - delete m_statement_list_ptr; - delete m_queue_type_ptr; -} - -void InPortDeclAST::generate() -{ - string code; - Type* queue_type_ptr = m_var_expr_ptr->generate(code); - if (!queue_type_ptr->isInPort()) { - error("Inport queues must be of a type that has the 'inport' attribute. The type '" + - queue_type_ptr->toString() + "' does not have this attribute."); - } - - Type* type_ptr = m_queue_type_ptr->lookupType(); - Var* in_port_ptr = new Var(*m_ident_ptr, getLocation(), type_ptr, code, getPairs()); - g_sym_table.newSym(in_port_ptr); - - g_sym_table.pushFrame(); - Vector param_type_vec; - - // Check for Event - type_ptr = g_sym_table.getType("Event"); - if (type_ptr == NULL) { - error("in_port declarations require 'Event' enumeration to be defined"); - } - param_type_vec.insertAtBottom(type_ptr); - - // Check for Address - type_ptr = g_sym_table.getType("Address"); - if (type_ptr == NULL) { - error("in_port declarations require 'Address' type to be defined"); - } - param_type_vec.insertAtBottom(type_ptr); - - // Add the trigger method - FIXME, this is a bit dirty - Map pairs; - pairs.add("external", "yes"); - Vector string_vec; - g_sym_table.newSym(new Func("trigger", getLocation(), g_sym_table.getType("void"), param_type_vec, string_vec, string(""), pairs, NULL)); - - // Check for Event2 - type_ptr = g_sym_table.getType("Event"); - if (type_ptr == NULL) { - error("in_port declarations require 'Event' enumeration to be defined"); - } - param_type_vec.insertAtBottom(type_ptr); - - // Check for Address2 - type_ptr = g_sym_table.getType("Address"); - if (type_ptr == NULL) { - error("in_port declarations require 'Address' type to be defined"); - } - param_type_vec.insertAtBottom(type_ptr); - - // Add the doubleTrigger method - this hack supports tiggering two simulateous events - // The key is that the second transistion cannot fail because the first event cannot be undone - // therefore you must do some checks before calling double trigger to ensure that won't happen - g_sym_table.newSym(new Func("doubleTrigger", getLocation(), g_sym_table.getType("void"), param_type_vec, string_vec, string(""), pairs, NULL)); - - // Add the continueProcessing method - this hack supports messages that don't trigger events - Vector empty_param_type_vec; - Vector empty_string_vec; - g_sym_table.newSym(new Func("continueProcessing", getLocation(), g_sym_table.getType("void"), empty_param_type_vec, empty_string_vec, string(""), pairs, NULL)); - - if (m_statement_list_ptr != NULL) { - inc_indent(); - inc_indent(); - string code; - m_statement_list_ptr->generate(code, NULL); - in_port_ptr->addPair("c_code_in_port", code); - dec_indent(); - dec_indent(); - } - g_sym_table.popFrame(); - - // Add port to state machine - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr == NULL) { - error("InPort declaration not part of a machine."); - } - machine_ptr->addInPort(in_port_ptr); -} - - -void InPortDeclAST::print(ostream& out) const -{ - out << "[InPortDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/InPortDeclAST.hh b/src/mem/slicc/ast/InPortDeclAST.hh deleted file mode 100644 index e6295a6e22..0000000000 --- a/src/mem/slicc/ast/InPortDeclAST.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InPortDeclAST.hh - * - * Description: - * - * $Id: InPortDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef InPortDeclAST_H -#define InPortDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" - -class InPortDeclAST : public DeclAST { -public: - // Constructors - InPortDeclAST(string* ident_ptr, - TypeAST* msg_type_ptr, - ExprAST* var_expr_ptr, - PairListAST* pairs_ptr, - StatementListAST* statement_list_ptr); - - // Destructor - ~InPortDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - InPortDeclAST(const InPortDeclAST& obj); - InPortDeclAST& operator=(const InPortDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_msg_type_ptr; - ExprAST* m_var_expr_ptr; - StatementListAST* m_statement_list_ptr; - TypeAST* m_queue_type_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const InPortDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const InPortDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //InPortDeclAST_H diff --git a/src/mem/slicc/ast/InPortDeclAST.py b/src/mem/slicc/ast/InPortDeclAST.py new file mode 100644 index 0000000000..3dde24557e --- /dev/null +++ b/src/mem/slicc/ast/InPortDeclAST.py @@ -0,0 +1,130 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.DeclAST import DeclAST +from slicc.ast.TypeAST import TypeAST +from slicc.symbols import Func, Type, Var + +class InPortDeclAST(DeclAST): + def __init__(self, slicc, ident, msg_type, var_expr, pairs, statements): + super(InPortDeclAST, self).__init__(slicc, pairs) + + self.ident = ident + self.msg_type = msg_type + self.var_expr = var_expr + self.statements = statements + self.queue_type = TypeAST(slicc, "InPort") + + def __repr__(self): + return "[InPortDecl: %s]" % self.ident + + def generate(self): + symtab = self.symtab + void_type = symtab.find("void", Type) + + code = code_formatter() + queue_type = self.var_expr.generate(code) + if not queue_type.isInPort: + self.error("The inport queue's type must have the 'inport' " + \ + "attribute. Type '%s' does not have this attribute.", + queue_type) + + type = self.queue_type.type + in_port = Var(self.symtab, self.ident, self.location, type, str(code), + self.pairs) + symtab.newSymbol(in_port) + + symtab.pushFrame() + param_types = [] + + # Check for Event + type = symtab.find("Event", Type) + if type is None: + self.error("in_port decls require 'Event' enumeration defined") + param_types.append(type) + + # Check for Address + type = symtab.find("Address", Type) + if type is None: + self.error("in_port decls require 'Address' type to be defined") + + param_types.append(type) + + # Add the trigger method - FIXME, this is a bit dirty + pairs = { "external" : "yes" } + func = Func(self.symtab, "trigger", self.location, void_type, + param_types, [], "", pairs, None) + symtab.newSymbol(func) + + param_types = [] + # Check for Event2 + type = symtab.find("Event", Type) + if type is None: + self.error("in_port decls require 'Event' enumeration") + + param_types.append(type) + + # Check for Address2 + type = symtab.find("Address", Type) + if type is None: + self.error("in_port decls require 'Address' type to be defined") + + param_types.append(type) + + # Add the doubleTrigger method - this hack supports tiggering + # two simulateous events + # + # The key is that the second transistion cannot fail because + # the first event cannot be undone therefore you must do some + # checks before calling double trigger to ensure that won't + # happen + func = Func(self.symtab, "doubleTrigger", self.location, void_type, + param_types, [], "", pairs, None) + symtab.newSymbol(func) + + # Add the continueProcessing method - this hack supports + # messages that don't trigger events + func = Func(self.symtab, "continueProcessing", self.location, + void_type, [], [], "", pairs, None) + symtab.newSymbol(func) + + if self.statements is not None: + rcode = code_formatter() + rcode.indent() + rcode.indent() + self.statements.generate(rcode, None) + in_port["c_code_in_port"] = str(rcode) + symtab.popFrame() + + # Add port to state machine + machine = symtab.state_machine + if machine is None: + self.error("InPort declaration not part of a machine.") + + machine.addInPort(in_port) diff --git a/src/mem/slicc/ast/InfixOperatorExprAST.cc b/src/mem/slicc/ast/InfixOperatorExprAST.cc deleted file mode 100644 index 40719fc667..0000000000 --- a/src/mem/slicc/ast/InfixOperatorExprAST.cc +++ /dev/null @@ -1,121 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InfixOperatorExprAST.C - * - * Description: See InfixOperatorExprAST.hh - * - * $Id: InfixOperatorExprAST.C,v 3.2 2004/01/31 20:46:15 milo Exp $ - * - */ - -#include "mem/slicc/ast/InfixOperatorExprAST.hh" - -InfixOperatorExprAST::InfixOperatorExprAST(ExprAST* left_ptr, - string* op_ptr, - ExprAST* right_ptr) - : ExprAST() -{ - m_left_ptr = left_ptr; - m_op_ptr = op_ptr; - m_right_ptr = right_ptr; -} - -InfixOperatorExprAST::~InfixOperatorExprAST() -{ - delete m_left_ptr; - delete m_op_ptr; - delete m_right_ptr; -} - -Type* InfixOperatorExprAST::generate(string& code) const -{ - code += "("; - Type* left_type_ptr = m_left_ptr->generate(code); - code += " " + *m_op_ptr + " "; - Type* right_type_ptr = m_right_ptr->generate(code); - code += ")"; - - string inputs, output; - // Figure out what the input and output types should be - if ((*m_op_ptr == "==" || - *m_op_ptr == "!=")) { - output = "bool"; - if (left_type_ptr != right_type_ptr) { - error("Type mismatch: left & right operand of operator '" + *m_op_ptr + - "' must be the same type." + - "left: '" + left_type_ptr->toString() + - "', right: '" + right_type_ptr->toString() + "'"); - } - } else { - if ((*m_op_ptr == "&&" || - *m_op_ptr == "||")) { - // boolean inputs and output - inputs = "bool"; - output = "bool"; - } else if ((*m_op_ptr == "==" || - *m_op_ptr == "!=" || - *m_op_ptr == ">=" || - *m_op_ptr == "<=" || - *m_op_ptr == ">" || - *m_op_ptr == "<")) { - // Integer inputs, boolean output - inputs = "int"; - output = "bool"; - } else { - // integer inputs and output - inputs = "int"; - output = "int"; - } - - Type* inputs_type = g_sym_table.getType(inputs); - - if (inputs_type != left_type_ptr) { - m_left_ptr->error("Type mismatch: left operand of operator '" + *m_op_ptr + - "' expects input type '" + inputs + "', actual was " + left_type_ptr->toString() + "'"); - } - - if (inputs_type != right_type_ptr) { - m_right_ptr->error("Type mismatch: right operand of operator '" + *m_op_ptr + - "' expects input type '" + inputs + "', actual was '" + right_type_ptr->toString() + "'"); - } - } - - // All is well - Type* output_type = g_sym_table.getType(output); - return output_type; -} - - -void InfixOperatorExprAST::print(ostream& out) const -{ - out << "[InfixExpr: " << *m_left_ptr - << *m_op_ptr << *m_right_ptr << "]"; -} diff --git a/src/mem/slicc/ast/InfixOperatorExprAST.hh b/src/mem/slicc/ast/InfixOperatorExprAST.hh deleted file mode 100644 index f97ab8805d..0000000000 --- a/src/mem/slicc/ast/InfixOperatorExprAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * InfixOperatorExprAST.hh - * - * Description: - * - * $Id: InfixOperatorExprAST.hh,v 3.1 2001/12/12 01:00:19 milo Exp $ - * - */ - -#ifndef INFIXOPERATOREXPRAST_H -#define INFIXOPERATOREXPRAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" - - -class InfixOperatorExprAST : public ExprAST { -public: - // Constructors - InfixOperatorExprAST(ExprAST* left_ptr, string* op_ptr, ExprAST* right_ptr); - - // Destructor - ~InfixOperatorExprAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - InfixOperatorExprAST(const InfixOperatorExprAST& obj); - InfixOperatorExprAST& operator=(const InfixOperatorExprAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_left_ptr; - string* m_op_ptr; - ExprAST* m_right_ptr; - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const InfixOperatorExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const InfixOperatorExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //INFIXOPERATOREXPRAST_H diff --git a/src/mem/slicc/ast/InfixOperatorExprAST.py b/src/mem/slicc/ast/InfixOperatorExprAST.py new file mode 100644 index 0000000000..c4fb4a4db8 --- /dev/null +++ b/src/mem/slicc/ast/InfixOperatorExprAST.py @@ -0,0 +1,89 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Type + +class InfixOperatorExprAST(ExprAST): + def __init__(self, slicc, left, op, right): + super(InfixOperatorExprAST, self).__init__(slicc) + + self.left = left + self.op = op + self.right = right + + def __repr__(self): + return "[InfixExpr: %r %s %r]" % (self.left, self.op, self.right) + + def generate(self, code): + lcode = code_formatter() + rcode = code_formatter() + + ltype = self.left.generate(lcode) + rtype = self.right.generate(rcode) + + # Figure out what the input and output types should be + if self.op in ("==", "!="): + output = "bool" + if (ltype != rtype): + self.error("Type mismatch: left and right operands of " + + "operator '%s' must be the same type. " + + "left: '%s', right: '%s'", + self.op, ltype, rtype) + else: + if self.op in ("&&", "||"): + # boolean inputs and output + inputs = "bool" + output = "bool" + elif self.op in ("==", "!=", ">=", "<=", ">", "<"): + # Integer inputs, boolean output + inputs = "int" + output = "bool" + else: + # integer inputs and output + inputs = "int" + output = "int" + + inputs_type = self.symtab.find(inputs, Type) + + if inputs_type != ltype: + self.left.error("Type mismatch: left operand of operator " + + "'%s' expects type '%s', actual was '%s'", + self.op, inputs, ltype) + + if inputs_type != rtype: + self.right.error("Type mismatch: right operand of operator " + + "'%s' expects type '%s', actual was '%s'", + self.op, inputs, rtype) + + # All is well + fix = code.nofix() + code("($lcode ${{self.op}} $rcode)") + code.fix(fix) + return self.symtab.find(output, Type) diff --git a/src/mem/slicc/ast/LiteralExprAST.cc b/src/mem/slicc/ast/LiteralExprAST.cc deleted file mode 100644 index 4e384a3b34..0000000000 --- a/src/mem/slicc/ast/LiteralExprAST.cc +++ /dev/null @@ -1,55 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * LiteralExprAST.C - * - * Description: See LiteralExprAST.hh - * - * $Id: LiteralExprAST.C,v 3.1 2002/10/22 21:27:52 milo Exp $ - * - */ - -#include "mem/slicc/ast/LiteralExprAST.hh" - -Type* LiteralExprAST::generate(string& code) const -{ - if (m_type == "string") { - code += "(\"" + *m_lit_ptr + "\")"; - } else { - code += "(" + *m_lit_ptr + ")"; - } - - Type* type_ptr = g_sym_table.getType(m_type); - if (type_ptr == NULL) { - // Can't find the type - error("Internal: can't primitive type '" + m_type + "'"); - } - return type_ptr; -} diff --git a/src/mem/slicc/ast/LiteralExprAST.hh b/src/mem/slicc/ast/LiteralExprAST.hh deleted file mode 100644 index c895fa9aef..0000000000 --- a/src/mem/slicc/ast/LiteralExprAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * LiteralExprAST.hh - * - * Description: - * - * $Id: LiteralExprAST.hh,v 3.1 2001/12/12 01:00:20 milo Exp $ - * - */ - -#ifndef LITERALEXPRAST_H -#define LITERALEXPRAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" - - -class LiteralExprAST : public ExprAST { -public: - // Constructors - LiteralExprAST(string* lit_ptr, string type) : ExprAST() { m_lit_ptr = lit_ptr; m_type = type; } - - // Destructor - ~LiteralExprAST() { delete m_lit_ptr; } - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const { out << "[Literal: " << *m_lit_ptr << "]"; } -private: - // Private Methods - - // Private copy constructor and assignment operator - LiteralExprAST(const LiteralExprAST& obj); - LiteralExprAST& operator=(const LiteralExprAST& obj); - - // Data Members (m_ prefix) - string* m_lit_ptr; - string m_type; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const LiteralExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const LiteralExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //LITERALEXPRAST_H diff --git a/src/mem/slicc/ast/LiteralExprAST.py b/src/mem/slicc/ast/LiteralExprAST.py new file mode 100644 index 0000000000..773e8f35c5 --- /dev/null +++ b/src/mem/slicc/ast/LiteralExprAST.py @@ -0,0 +1,55 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Type + +class LiteralExprAST(ExprAST): + def __init__(self, slicc, literal, type): + super(LiteralExprAST, self).__init__(slicc) + self.literal = literal + self.type = type + + def __repr__(self): + return "[Literal: %s]" % self.literal + + def generate(self, code): + fix = code.nofix() + if self.type == "string": + code('("${{self.literal}}")') + elif self.type == "bool": + code('(${{str(self.literal).lower()}})') + else: + code('(${{self.literal}})') + code.fix(fix) + + type = self.symtab.find(self.type, Type) + if type is None: + # Can't find the type + self.error("Internal: can't primitive type '%s'" % self.type) + + return type diff --git a/src/mem/slicc/ast/Location.cc b/src/mem/slicc/ast/Location.cc deleted file mode 100644 index fd224fe2fe..0000000000 --- a/src/mem/slicc/ast/Location.cc +++ /dev/null @@ -1,87 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Location.C - * - * Description: See Location.hh - * - * $Id: Location.C,v 3.3 2004/05/30 22:19:02 kmoore Exp $ - * - */ - -#include "mem/slicc/ast/Location.hh" - -int g_line_number = 0; -string &g_file_name() -{ - static string the_string; - return the_string; -} - -Location::Location() -{ - m_file_name = g_file_name(); - m_line_number = g_line_number; - - ostringstream sstr; - sstr << getLineNumber(); - m_line_number_str = sstr.str(); -} - -void Location::error(string err_msg) const -{ - cerr << endl; - cerr << toString() << ": Error: " << err_msg << endl; - exit(1); -} - -string Location::embedError(string err_msg) const -{ - string code; - code += "cerr << \"Runtime Error at "; - code += toString() + ", Ruby Time: \" << "; - code += "g_eventQueue_ptr->getTime() << \": \" << "; - code += err_msg; - code += " << \", PID: \" << getpid() << endl;\n"; - code += "char c; cerr << \"press return to continue.\" << endl; cin.get(c); abort();\n"; - - return code; -} - -void Location::warning(string err_msg) const -{ - cerr << toString() << ": Warning: " - << err_msg << endl; -} - -string Location::toString() const -{ - return m_file_name + ":" + m_line_number_str; -} diff --git a/src/mem/slicc/ast/Location.hh b/src/mem/slicc/ast/Location.hh deleted file mode 100644 index c9e20418e0..0000000000 --- a/src/mem/slicc/ast/Location.hh +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Location.hh - * - * Description: - * - * $Id: Location.hh,v 3.1 2001/12/12 01:00:20 milo Exp $ - * - */ - -#ifndef LOCATION_H -#define LOCATION_H - -#include "mem/slicc/slicc_global.hh" - -extern int g_line_number; -extern string &g_file_name(); - -class Location { -public: - // Constructors - Location(); - - // Destructor - //~Location(); - - // Public Methods - - void print(ostream& out) const; - void error(string err_msg) const; - string embedError(string err_msg) const; - void warning(string err_msg) const; - string toString() const; - -private: - // Private Methods - const string& getFileName() const { return m_file_name; } - int getLineNumber() const { return m_line_number; } - string getLineNumberStr() const { return m_line_number_str; } - - // Private copy constructor and assignment operator - //Location(const Location& obj); - //Location& operator=(const Location& obj); - - // Data Members (m_ prefix) - string m_file_name; - int m_line_number; - string m_line_number_str; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Location& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Location& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //LOCATION_H diff --git a/src/mem/slicc/ast/MachineAST.cc b/src/mem/slicc/ast/MachineAST.cc deleted file mode 100644 index ae80264584..0000000000 --- a/src/mem/slicc/ast/MachineAST.cc +++ /dev/null @@ -1,99 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * MachineAST.cc - * - * Description: See MachineAST.hh - * - * $Id: MachineAST.cc,v 3.1 2003/03/17 01:54:25 xu Exp $ - * - */ - -#include "mem/slicc/ast/MachineAST.hh" -#include "mem/slicc/ast/FormalParamAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -MachineAST::MachineAST(string* ident_ptr, - PairListAST* pairs_ptr, - Vector* config_parameters, - DeclListAST* decl_list_ptr) - - : DeclAST(pairs_ptr) -{ - m_ident_ptr = ident_ptr; - m_pairs_ptr = pairs_ptr; - m_config_parameters = config_parameters; - m_decl_list_ptr = decl_list_ptr; -} - -MachineAST::~MachineAST() -{ - delete m_ident_ptr; - delete m_pairs_ptr; - delete m_decl_list_ptr; -} - -void MachineAST::generate() -{ - StateMachine* machine_ptr; - - // Make a new frame - g_sym_table.pushFrame(); - - // Create a new machine - machine_ptr = new StateMachine(*m_ident_ptr, getLocation(), getPairs(), m_config_parameters); - g_sym_table.newCurrentMachine(machine_ptr); - - // Generate code for all the internal decls - m_decl_list_ptr->generate(); - - // Build the transition table - machine_ptr->buildTable(); - - // Pop the frame - g_sym_table.popFrame(); -} - -void MachineAST::findMachines() -{ - // Add to MachineType enumeration - Type* type_ptr = g_sym_table.getType("MachineType"); - if (!type_ptr->enumAdd(*m_ident_ptr, m_pairs_ptr->getPairs())) { - error("Duplicate machine name: " + type_ptr->toString() + ":" + *m_ident_ptr); - } - - // Generate code for all the internal decls - m_decl_list_ptr->findMachines(); -} - -void MachineAST::print(ostream& out) const -{ - out << "[Machine: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/MachineAST.hh b/src/mem/slicc/ast/MachineAST.hh deleted file mode 100644 index 5d1bc2a1cd..0000000000 --- a/src/mem/slicc/ast/MachineAST.hh +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ActionDeclAST.hh - * - * Description: - * - * $Id: MachineAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef MachineAST_H -#define MachineAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/DeclListAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -class FormalParamAST; - -class MachineAST : public DeclAST { -public: - // Constructors - MachineAST(string* ident_ptr, - PairListAST* pairs_ptr, - Vector* config_parameters, - DeclListAST* decl_list_ptr); - - // Destructor - ~MachineAST(); - - // Public Methods - void print(ostream& out) const; - void generate(); - void findMachines(); -private: - // Private Methods - - // Private copy constructor and assignment operator - MachineAST(const MachineAST& obj); - MachineAST& operator=(const MachineAST& obj); - - // Data Members (m_ prefix) - Vector* m_config_parameters; - string* m_ident_ptr; - DeclListAST* m_decl_list_ptr; - PairListAST* m_pairs_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const MachineAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const MachineAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //MachineAST_H diff --git a/src/mem/slicc/ast/MachineAST.py b/src/mem/slicc/ast/MachineAST.py new file mode 100644 index 0000000000..8d48ccbf58 --- /dev/null +++ b/src/mem/slicc/ast/MachineAST.py @@ -0,0 +1,81 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import StateMachine, Type + +class MachineAST(DeclAST): + def __init__(self, slicc, ident, pairs_ast, config_parameters, decls): + super(MachineAST, self).__init__(slicc, pairs_ast) + + self.ident = ident + self.pairs_ast = pairs_ast + self.config_parameters = config_parameters + self.decls = decls + + def __repr__(self): + return "[Machine: %r]" % self.ident + + def files(self, hh, cc, parent=None): + hh.add('%s_Controller.hh' % self.ident) + hh.add('%s_Profiler.hh' % self.ident) + + cc.add('%s_Controller.cc' % self.ident) + cc.add('%s_Profiler.cc' % self.ident) + cc.add('%s_Transitions.cc' % self.ident) + cc.add('%s_Wakeup.cc' % self.ident) + + self.decls.files(hh, cc, self.ident) + + def generate(self): + # Make a new frame + self.symtab.pushFrame() + + # Create a new machine + machine = StateMachine(self.symtab, self.ident, self.location, + self.pairs, self.config_parameters) + + self.symtab.newCurrentMachine(machine) + + # Generate code for all the internal decls + self.decls.generate() + + # Build the transition table + machine.buildTable() + + # Pop the frame + self.symtab.popFrame() + + def findMachines(self): + # Add to MachineType enumeration + machine_type = self.symtab.find("MachineType", Type) + if not machine_type.enumAdd(self.ident, self.pairs_ast.pairs): + self.error("Duplicate machine name: %s:%s" % (machine_type, + self.ident)) + + # Generate code for all the internal decls + self.decls.findMachines() diff --git a/src/mem/slicc/ast/MemberExprAST.cc b/src/mem/slicc/ast/MemberExprAST.cc deleted file mode 100644 index 1bcfdc7f17..0000000000 --- a/src/mem/slicc/ast/MemberExprAST.cc +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * FieldExprAST.C - * - * Description: See FieldExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/MemberExprAST.hh" - -MemberExprAST::MemberExprAST(ExprAST* expr_ast_ptr, string* field_ptr) - : ExprAST() -{ - m_expr_ast_ptr = expr_ast_ptr; - m_field_ptr = field_ptr; -} - -MemberExprAST::~MemberExprAST() -{ - delete m_expr_ast_ptr; - delete m_field_ptr; -} - -Type* MemberExprAST::generate(string& code) const -{ - code += "("; - Type* type_ptr = m_expr_ast_ptr->generate(code); - code += ").m_" + (*m_field_ptr); - - // Verify that this is a valid field name for this type - if (!type_ptr->dataMemberExist(*m_field_ptr)) { - error("Invalid object field: Type '" + type_ptr->toString() + "' does not have data member " + *m_field_ptr); - } - - // Return the type of the field - return type_ptr->dataMemberType(*m_field_ptr); -} - -void MemberExprAST::print(ostream& out) const -{ - out << "[MemberExprAST: " << *m_expr_ast_ptr << "." << *m_field_ptr << "]"; -} diff --git a/src/mem/slicc/ast/MemberExprAST.hh b/src/mem/slicc/ast/MemberExprAST.hh deleted file mode 100644 index 34b694882e..0000000000 --- a/src/mem/slicc/ast/MemberExprAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * MemberExprAST.hh - * - * Description: - * - * $Id: MemberExprAST.hh,v 3.1 2001/12/12 01:00:21 milo Exp $ - * - */ - -#ifndef MemberExprAST_H -#define MemberExprAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" - - -class MemberExprAST : public ExprAST { -public: - // Constructors - MemberExprAST(ExprAST* expr_ast_ptr, string* field_ptr); - - // Destructor - ~MemberExprAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - MemberExprAST(const MemberExprAST& obj); - MemberExprAST& operator=(const MemberExprAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_expr_ast_ptr; - string* m_field_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const MemberExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const MemberExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //MemberExprAST_H diff --git a/src/mem/slicc/ast/MemberExprAST.py b/src/mem/slicc/ast/MemberExprAST.py new file mode 100644 index 0000000000..113bb188a4 --- /dev/null +++ b/src/mem/slicc/ast/MemberExprAST.py @@ -0,0 +1,55 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.ExprAST import ExprAST + +class MemberExprAST(ExprAST): + def __init__(self, slicc, expr_ast, field): + super(MemberExprAST, self).__init__(slicc) + + self.expr_ast = expr_ast + self.field = field + + def __repr__(self): + return "[MemberExprAST: %r.%r]" % (self.expr_ast, self.field) + + def generate(self, code): + return_type, gcode = self.expr_ast.inline(True) + fix = code.nofix() + code("($gcode).m_${{self.field}}") + code.fix(fix) + + # Verify that this is a valid field name for this type + if self.field not in return_type.data_members: + error("Invalid object field: " + + "Type '%s' does not have data member %s" % \ + (return_type, self.field)) + + # Return the type of the field + return return_type.data_members[self.field].type diff --git a/src/mem/slicc/ast/MethodCallExprAST.cc b/src/mem/slicc/ast/MethodCallExprAST.cc deleted file mode 100644 index 1bfe312ff5..0000000000 --- a/src/mem/slicc/ast/MethodCallExprAST.cc +++ /dev/null @@ -1,160 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * MethodCallExprAST.cc - * - * Description: See MethodCallExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/MethodCallExprAST.hh" - -MethodCallExprAST::MethodCallExprAST(ExprAST* obj_expr_ptr, - string* proc_name_ptr, - Vector* expr_vec_ptr) - : ExprAST() -{ - m_obj_expr_ptr = obj_expr_ptr; - m_type_ptr = NULL; - m_proc_name_ptr = proc_name_ptr; - m_expr_vec_ptr = expr_vec_ptr; -} - -MethodCallExprAST::MethodCallExprAST(TypeAST* type_ptr, - string* proc_name_ptr, - Vector* expr_vec_ptr) - : ExprAST() -{ - m_obj_expr_ptr = NULL; - m_type_ptr = type_ptr; - m_proc_name_ptr = proc_name_ptr; - m_expr_vec_ptr = expr_vec_ptr; -} - -MethodCallExprAST::~MethodCallExprAST() -{ - delete m_obj_expr_ptr; - delete m_type_ptr; - delete m_proc_name_ptr; - int size = m_expr_vec_ptr->size(); - for(int i=0; i paramTypes; - - int actual_size = m_expr_vec_ptr->size(); - for(int i=0; igenerate(tmp); - paramTypes.insertAtBottom(actual_type_ptr); - } - - if(m_obj_expr_ptr) { - // member method call - string tmp; - obj_type_ptr = m_obj_expr_ptr->generate(tmp); - methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes); - if (obj_type_ptr->methodReturnType(methodId)->isInterface()) - code += "static_cast<" + obj_type_ptr->methodReturnType(methodId)->cIdent() + "&>"; - code += "(("; - code += tmp; - code += ")."; - } else if (m_type_ptr) { - // class method call - code += "(" + m_type_ptr->toString() + "::"; - obj_type_ptr = m_type_ptr->lookupType(); - methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes); - } else { - // impossible - assert(0); - } - - // generate code - actual_size = m_expr_vec_ptr->size(); - code += (*m_proc_name_ptr) + "("; - for(int i=0; igenerate(code); - } - code += "))"; - - // Verify that this is a method of the object - if (!obj_type_ptr->methodExist(methodId)) { - error("Invalid method call: Type '" + obj_type_ptr->toString() + "' does not have a method '" + methodId + "'"); - } - - int expected_size = obj_type_ptr->methodParamType(methodId).size(); - if (actual_size != expected_size) { - // Right number of parameters - ostringstream err; - err << "Wrong number of parameters for function name: '" << *m_proc_name_ptr << "'"; - err << ", expected: "; - err << expected_size; - err << ", actual: "; - err << actual_size; - error(err.str()); - } - - for(int i=0; imethodParamType(methodId)[i]; - if (actual_type_ptr != expected_type_ptr) { - (*m_expr_vec_ptr)[i]->error("Type mismatch: expected: " + expected_type_ptr->toString() + - " actual: " + actual_type_ptr->toString()); - } - } - - // Return the return type of the method - return obj_type_ptr->methodReturnType(methodId); -} - -void MethodCallExprAST::findResources(Map& resource_list) const -{ - -} - -void MethodCallExprAST::print(ostream& out) const -{ - out << "[MethodCallExpr: " << *m_proc_name_ptr << *m_obj_expr_ptr << " " << *m_expr_vec_ptr << "]"; -} diff --git a/src/mem/slicc/ast/MethodCallExprAST.hh b/src/mem/slicc/ast/MethodCallExprAST.hh deleted file mode 100644 index d248e6ba47..0000000000 --- a/src/mem/slicc/ast/MethodCallExprAST.hh +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * MethodCallExprAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef MethodCallExprAST_H -#define MethodCallExprAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class MethodCallExprAST : public ExprAST { -public: - // Constructors - MethodCallExprAST(ExprAST* m_obj_expr_ptr, - string* proc_name_ptr, - Vector* expr_vec_ptr); - - MethodCallExprAST(TypeAST* type_ptr, - string* proc_name_ptr, - Vector* expr_vec_ptr); - - // Destructor - ~MethodCallExprAST(); - - // Public Methods - Type* generate(string& code) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - MethodCallExprAST(const MethodCallExprAST& obj); - MethodCallExprAST& operator=(const MethodCallExprAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_obj_expr_ptr; - TypeAST* m_type_ptr; - string* m_proc_name_ptr; - Vector* m_expr_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const MethodCallExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const MethodCallExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif // MethodCallExprAST_H diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py new file mode 100644 index 0000000000..ecfe43cdbd --- /dev/null +++ b/src/mem/slicc/ast/MethodCallExprAST.py @@ -0,0 +1,127 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.ExprAST import ExprAST + +class MethodCallExprAST(ExprAST): + def __init__(self, slicc, proc_name, expr_ast_vec): + super(MethodCallExprAST, self).__init__(slicc) + self.proc_name = proc_name + self.expr_ast_vec = expr_ast_vec + + def generate(self, code): + tmp = code_formatter() + paramTypes = [] + for expr_ast in self.expr_ast_vec: + return_type = expr_ast.generate(tmp) + paramTypes.append(return_type) + + obj_type, methodId, prefix = self.generate_prefix(paramTypes) + + # generate code + params = [] + for expr_ast in self.expr_ast_vec: + return_type,tcode = expr_ast.inline(True) + params.append(str(tcode)) + fix = code.nofix() + code("$prefix${{self.proc_name}}(${{', '.join(params)}}))") + code.fix(fix) + + # Verify that this is a method of the object + if methodId not in obj_type.methods: + error("Invalid method call: Type '%s' does not have a method '%s'", + obj_type, methodId) + + if len(self.expr_ast_vec) != \ + len(obj_type.methods[methodId].param_types): + # Right number of parameters + error("Wrong number of parameters for function name: '%s', " + \ + "expected: , actual: ", proc_name, + len(obj_type.methods[methodId].param_types), + len(self.expr_ast_vec)) + + for actual_type, expected_type in \ + zip(paramTypes, obj_type.methods[methodId].param_types): + if actual_type != expected_type: + error("Type mismatch: expected: %s actual: %s", + expected_type, actual_type) + + # Return the return type of the method + return obj_type.methods[methodId].return_type + + def findResources(self, resources): + pass + +class MemberMethodCallExprAST(MethodCallExprAST): + def __init__(self, slicc, obj_expr_ast, proc_name, expr_ast_vec): + s = super(MemberMethodCallExprAST, self) + s.__init__(slicc, proc_name, expr_ast_vec) + + self.obj_expr_ast = obj_expr_ast + + def __repr__(self): + return "[MethodCallExpr: %r%r %r]" % (self.proc_name, + self.obj_expr_ast, + self.expr_ast_vec) + def generate_prefix(self, paramTypes): + code = code_formatter() + + # member method call + obj_type = self.obj_expr_ast.generate(code) + methodId = obj_type.methodId(self.proc_name, paramTypes) + + prefix = "" + return_type = obj_type.methods[methodId].return_type + if return_type.isInterface: + prefix = "static_cast<%s &>" % return_type.c_ident + prefix = "%s((%s)." % (prefix, code) + + return obj_type, methodId, prefix + + +class ClassMethodCallExprAST(MethodCallExprAST): + def __init__(self, slicc, type_ast, proc_name, expr_ast_vec): + s = super(ClassMethodCallExprAST, self) + s.__init__(slicc, proc_name, expr_ast_vec) + + self.type_ast = type_ast + + def __repr__(self): + return "[MethodCallExpr: %r %r]" % (self.proc_name, self.expr_ast_vec) + + def generate_prefix(self, paramTypes): + + # class method call + prefix = "(%s::" % self.type_ast + obj_type = self.type_ast.type + methodId = obj_type.methodId(self.proc_name, paramTypes) + + return obj_type, methodId, prefix + +__all__ = [ "MemberMethodCallExprAST", "ClassMethodCallExprAST" ] diff --git a/src/mem/slicc/ast/NewExprAST.cc b/src/mem/slicc/ast/NewExprAST.cc deleted file mode 100644 index 95e57192f3..0000000000 --- a/src/mem/slicc/ast/NewExprAST.cc +++ /dev/null @@ -1,9 +0,0 @@ - -#include "mem/slicc/ast/NewExprAST.hh" - -Type* NewExprAST::generate(string & code) const -{ - Type* type = m_type_ptr->lookupType(); - code += "new " + type->cIdent(); - return type; -} diff --git a/src/mem/slicc/ast/NewExprAST.hh b/src/mem/slicc/ast/NewExprAST.hh deleted file mode 100644 index 375f130d66..0000000000 --- a/src/mem/slicc/ast/NewExprAST.hh +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef NEWEXPRAST_H -#define NEWEXPRAST_H - -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/symbols/Type.hh" - -class NewExprAST : public ExprAST -{ -public: - NewExprAST(TypeAST* type_ptr) : ExprAST() { m_type_ptr = type_ptr; } - Type* generate(string & code) const; - void print(ostream & out) const { out << "[NewExprAST: " << *m_type_ptr << "]"; } - string getName() const { return m_type_ptr->toString(); } - -private: - TypeAST* m_type_ptr; -}; - -#endif diff --git a/src/mem/slicc/ast/NewExprAST.py b/src/mem/slicc/ast/NewExprAST.py new file mode 100644 index 0000000000..a423507683 --- /dev/null +++ b/src/mem/slicc/ast/NewExprAST.py @@ -0,0 +1,47 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST + +class NewExprAST(ExprAST): + def __init__(self, slicc, type_ast): + super(NewExprAST, self).__init__(slicc) + self.type_ast = type_ast + + def __repr__(self): + return "[NewExprAST: %r]" % self.type_ast + + @property + def name(self): + return str(self.type_ast) + + def generate(self, code): + type = self.type_ast.type + fix = code.nofix() + code("new ${{type.c_ident}}") + code.fix(fix) + return type diff --git a/src/mem/slicc/ast/ObjDeclAST.cc b/src/mem/slicc/ast/ObjDeclAST.cc deleted file mode 100644 index 3569395db4..0000000000 --- a/src/mem/slicc/ast/ObjDeclAST.cc +++ /dev/null @@ -1,137 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ObjDeclAST.cc - * - * Description: See ObjDeclAST.hh - * - * $Id: ObjDeclAST.cc,v 3.13 2004/06/24 15:56:14 beckmann Exp $ - * - */ - -#include "mem/slicc/ast/ObjDeclAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/main.hh" - -ObjDeclAST::ObjDeclAST(TypeAST* type_ptr, - string* ident_ptr, - PairListAST* pairs_ptr) - : DeclAST(pairs_ptr) -{ - m_type_ptr = type_ptr; - m_ident_ptr = ident_ptr; -} - -ObjDeclAST::~ObjDeclAST() -{ - delete m_type_ptr; - delete m_ident_ptr; -} - -void ObjDeclAST::generate() -{ - - bool machineComponentSym = false; - - getPairs().add("chip_object", "yes"); - - string c_code; - - - if (getPairs().exist("hack")) { - warning("'hack=' is now deprecated"); - } - - if (getPairs().exist("network")) { - if (!getPairs().exist("virtual_network")) { - error("Network queues require a 'virtual_network' attribute."); - } - } - - Type* type_ptr = m_type_ptr->lookupType(); - if (type_ptr->isBuffer()) { - if (!getPairs().exist("ordered")) { - error("Buffer object declarations require an 'ordered' attribute."); - } - } - - if (getPairs().exist("ordered")) { - string value = getPairs().lookup("ordered"); - if (value != "true" && value != "false") { - error("The 'ordered' attribute must be 'true' or 'false'."); - } - } - - if (getPairs().exist("random")) { - string value = getPairs().lookup("random"); - if (value != "true" && value != "false") { - error("The 'random' attribute must be 'true' or 'false'."); - } - } - - string machine; - if (g_sym_table.getStateMachine() != NULL) { - machine = g_sym_table.getStateMachine()->getIdent() + "_"; - } - - // FIXME : should all use accessors here to avoid public member variables - if (*m_ident_ptr == "id") { - c_code = "m_chip_ptr->getID()"; - } else if (*m_ident_ptr == "version") { - c_code = "m_version"; - } else if (*m_ident_ptr == "machineID") { - c_code = "m_machineID"; - } else { - c_code = "(*m_" + machine + *m_ident_ptr + "_ptr)"; - // c_code = "(*(m_chip_ptr->m_" + machine + *m_ident_ptr + "_ptr))"; - // machineComponentSym = true; - } - - Var* v = new Var(*m_ident_ptr, getLocation(), type_ptr, c_code, - getPairs(), g_sym_table.getStateMachine()); - - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr != NULL) { - machine_ptr->addObj(v); - }// else { - g_sym_table.newSym(v); - //} - - // used to cheat-- that is, access components in other machines - if (machineComponentSym) { - g_sym_table.newMachComponentSym(v); - } - -} - -void ObjDeclAST::print(ostream& out) const -{ - out << "[ObjDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/ObjDeclAST.hh b/src/mem/slicc/ast/ObjDeclAST.hh deleted file mode 100644 index 0b808f472c..0000000000 --- a/src/mem/slicc/ast/ObjDeclAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ObjDeclAST.hh - * - * Description: - * - * $Id: ObjDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef ObjDeclAST_H -#define ObjDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class ObjDeclAST : public DeclAST { -public: - // Constructors - ObjDeclAST(TypeAST* type_ptr, - string* ident_ptr, - PairListAST* pairs_ptr); - - // Destructor - ~ObjDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ObjDeclAST(const ObjDeclAST& obj); - ObjDeclAST& operator=(const ObjDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_type_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ObjDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ObjDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ObjDeclAST_H diff --git a/src/mem/slicc/ast/ObjDeclAST.py b/src/mem/slicc/ast/ObjDeclAST.py new file mode 100644 index 0000000000..8a967f7b88 --- /dev/null +++ b/src/mem/slicc/ast/ObjDeclAST.py @@ -0,0 +1,94 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Var + +class ObjDeclAST(DeclAST): + def __init__(self, slicc, type_ast, ident, pairs): + super(ObjDeclAST, self).__init__(slicc, pairs) + + self.type_ast = type_ast + self.ident = ident + + def __repr__(self): + return "[ObjDecl: %r]" % self.ident + + def generate(self): + machineComponentSym = False + + self["chip_object"] = "yes" + + if "hack" in self: + warning("'hack=' is now deprecated") + + if "network" in self and "virtual_network" not in self: + self.error("Network queues require a 'virtual_network' attribute") + + type = self.type_ast.type + if type.isBuffer and "ordered" not in self: + self.error("Buffer object decls require an 'ordered' attribute") + + if "ordered" in self: + value = self["ordered"] + + if value not in ("true", "false"): + self.error("The 'ordered' attribute is '%s' " + \ + "must be 'true' or 'false'.", value) + + if "random" in self: + value = self["random"] + if value not in ("true", "false"): + self.error("The 'random' attribute is '%s' " + \ + "must be 'true' or 'false'.", value) + + machine = self.symtab.state_machine + + # FIXME : should all use accessors here to avoid public member + # variables + if self.ident == "id": + c_code = "m_chip_ptr.getID()" + elif self.ident == "version": + c_code = "m_version" + elif self.ident == "machineID": + c_code = "m_machineID" + elif machine: + c_code = "(*m_%s_%s_ptr)" % (machine.ident, self.ident) + else: + c_code = "(*m_%s_ptr)" % (self.ident) + + v = Var(self.symtab, self.ident, self.location, type, c_code, + self.pairs, machine) + + if machine: + machine.addObject(v) + + self.symtab.newSymbol(v) + + # used to cheat-- that is, access components in other machines + if machineComponentSym: + self.symtab.newMachComponentSym(v) diff --git a/src/mem/slicc/ast/OutPortDeclAST.cc b/src/mem/slicc/ast/OutPortDeclAST.cc deleted file mode 100644 index 56a377f235..0000000000 --- a/src/mem/slicc/ast/OutPortDeclAST.cc +++ /dev/null @@ -1,79 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutPortDeclAST.C - * - * Description: See OutPortDeclAST.hh - * - * $Id: OutPortDeclAST.C,v 3.3 2004/02/02 22:37:51 milo Exp $ - * - */ - -#include "mem/slicc/ast/OutPortDeclAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -OutPortDeclAST::OutPortDeclAST(string* ident_ptr, - TypeAST* msg_type_ptr, - ExprAST* var_expr_ptr, - PairListAST* pairs_ptr) - : DeclAST(pairs_ptr) -{ - m_ident_ptr = ident_ptr; - m_msg_type_ptr = msg_type_ptr; - m_var_expr_ptr = var_expr_ptr; - m_queue_type_ptr = new TypeAST(new string("OutPort")); -} - -OutPortDeclAST::~OutPortDeclAST() -{ - delete m_ident_ptr; - delete m_msg_type_ptr; - delete m_var_expr_ptr; - delete m_queue_type_ptr; -} - -void OutPortDeclAST::generate() -{ - string code; - Type* queue_type_ptr = m_var_expr_ptr->generate(code); - if (!queue_type_ptr->isOutPort()) { - error("Outport queues must be of a type that has the 'outport' attribute. The type '" + - queue_type_ptr->toString() + "' does not have this attribute."); - } - - Type* type_ptr = m_queue_type_ptr->lookupType(); - g_sym_table.newSym(new Var(*m_ident_ptr, getLocation(), type_ptr, code, getPairs())); -} - - -void OutPortDeclAST::print(ostream& out) const -{ - out << "[OutPortDecl: " << *m_ident_ptr << "]"; -} diff --git a/src/mem/slicc/ast/OutPortDeclAST.hh b/src/mem/slicc/ast/OutPortDeclAST.hh deleted file mode 100644 index 0aa0172d3e..0000000000 --- a/src/mem/slicc/ast/OutPortDeclAST.hh +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * OutPortDeclAST.hh - * - * Description: - * - * $Id: OutPortDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $ - * - */ - -#ifndef OutPortDeclAST_H -#define OutPortDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" - -class OutPortDeclAST : public DeclAST { -public: - // Constructors - OutPortDeclAST(string* ident_ptr, - TypeAST* msg_type_ptr, - ExprAST* var_expr_ptr, - PairListAST* pairs_ptr); - - // Destructor - ~OutPortDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - OutPortDeclAST(const OutPortDeclAST& obj); - OutPortDeclAST& operator=(const OutPortDeclAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; - TypeAST* m_msg_type_ptr; - TypeAST* m_queue_type_ptr; - ExprAST* m_var_expr_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const OutPortDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const OutPortDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //OutPortDeclAST_H diff --git a/src/mem/slicc/ast/OutPortDeclAST.py b/src/mem/slicc/ast/OutPortDeclAST.py new file mode 100644 index 0000000000..e6ef319286 --- /dev/null +++ b/src/mem/slicc/ast/OutPortDeclAST.py @@ -0,0 +1,57 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.ast.DeclAST import DeclAST +from slicc.ast.TypeAST import TypeAST +from slicc.symbols import Var + +class OutPortDeclAST(DeclAST): + def __init__(self, slicc, ident, msg_type, var_expr, pairs): + super(OutPortDeclAST, self).__init__(slicc, pairs) + + self.ident = ident + self.msg_type = msg_type + self.var_expr = var_expr + self.queue_type = TypeAST(slicc, "OutPort") + + def __repr__(self): + return "[OutPortDecl: %r]" % self.ident + + def generate(self): + code = code_formatter(newlines=False) + + queue_type = self.var_expr.generate(code) + if not queue_type.isOutPort: + self.error("The outport queue's type must have the 'outport' " + + "attribute. Type '%s' does not have this attribute.", + (queue_type)) + + var = Var(self.symtab, self.ident, self.location, self.queue_type.type, + str(code), self.pairs) + self.symtab.newSymbol(var) diff --git a/src/mem/slicc/ast/PairAST.cc b/src/mem/slicc/ast/PairAST.cc deleted file mode 100644 index c42843ccec..0000000000 --- a/src/mem/slicc/ast/PairAST.cc +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PairAST.C - * - * Description: See PairAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/PairAST.hh" - -PairAST::PairAST(string* key_ptr, string* value_ptr) - : AST() -{ - m_key_ptr = key_ptr; - m_value_ptr = value_ptr; -} - -PairAST::PairAST(string key, string* value_ptr) - : AST() -{ - m_key_ptr = new string(key); - m_value_ptr = value_ptr; -} - -PairAST::PairAST(string key, string value) - : AST() -{ - m_key_ptr = new string(key); - m_value_ptr = new string(value); -} - -PairAST::~PairAST() -{ - delete m_key_ptr; - delete m_value_ptr; -} - -void PairAST::print(ostream& out) const -{ - out << "[" << *m_key_ptr << "=" << *m_value_ptr << "]" << endl; -} - diff --git a/src/mem/slicc/ast/PairAST.hh b/src/mem/slicc/ast/PairAST.hh deleted file mode 100644 index d1bb99b93f..0000000000 --- a/src/mem/slicc/ast/PairAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PairAST.hh - * - * Description: - * - * $Id: PairAST.hh,v 3.1 2001/12/12 01:00:24 milo Exp $ - * - */ - -#ifndef PAIRAST_H -#define PAIRAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" - -class PairAST : public AST { -public: - // Constructors - PairAST(string* key_ptr, string* value_ptr); - PairAST(string key, string* value_ptr); - PairAST(string key, string value); - - // Destructor - ~PairAST(); - - // Public Methods - string key() const { return *m_key_ptr; } - string value() const { return *m_value_ptr; } - - virtual void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - // PairAST(const PairAST& obj); - // PairAST& operator=(const PairAST& obj); - - // Data Members (m_ prefix) - string* m_key_ptr; - string* m_value_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const PairAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const PairAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //PAIRAST_H diff --git a/src/mem/slicc/ast/PairAST.py b/src/mem/slicc/ast/PairAST.py new file mode 100644 index 0000000000..347f4d361c --- /dev/null +++ b/src/mem/slicc/ast/PairAST.py @@ -0,0 +1,36 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class PairAST(AST): + def __init__(self, slicc, key, value): + super(PairAST, self).__init__(slicc) + self.key = key + self.value = value + + def __repr__(self): + return '[%s=%s]' % (self.key, self.value) diff --git a/src/mem/slicc/ast/PairListAST.cc b/src/mem/slicc/ast/PairListAST.cc deleted file mode 100644 index 76892d4371..0000000000 --- a/src/mem/slicc/ast/PairListAST.cc +++ /dev/null @@ -1,49 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PairListAST.C - * - * Description: See PairListAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/PairListAST.hh" - -void PairListAST::addPair(PairAST* pair_ptr) -{ - getPairs().add(pair_ptr->key(), pair_ptr->value()); -} - -void PairListAST::print(ostream& out) const -{ - out << "[PairListAST] " << getPairs(); -} diff --git a/src/mem/slicc/ast/PairListAST.hh b/src/mem/slicc/ast/PairListAST.hh deleted file mode 100644 index 7edcdc1e7f..0000000000 --- a/src/mem/slicc/ast/PairListAST.hh +++ /dev/null @@ -1,82 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PairListAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef PairListAST_H -#define PairListAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" -#include "mem/slicc/ast/PairAST.hh" - - -class PairListAST : public AST { -public: - // Constructors - PairListAST() : AST() {} - - // Destructor - //~PairListAST(); - - // Public Methods - void addPair(PairAST* pair_ptr); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - PairListAST(const PairListAST& obj); - PairListAST& operator=(const PairListAST& obj); - - // Data Members (m_ prefix) -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const PairListAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const PairListAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //PairListAST_H diff --git a/src/mem/slicc/ast/PairListAST.py b/src/mem/slicc/ast/PairListAST.py new file mode 100644 index 0000000000..6afe3f4fae --- /dev/null +++ b/src/mem/slicc/ast/PairListAST.py @@ -0,0 +1,37 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class PairListAST(AST): + def __init__(self, slicc): + super(PairListAST, self).__init__(slicc) + + def __repr__(self): + return "[PairListAST] %r" % self.pairs + + def addPair(self, pair_ast): + self[pair_ast.key] = pair_ast.value diff --git a/src/mem/slicc/ast/PeekStatementAST.cc b/src/mem/slicc/ast/PeekStatementAST.cc deleted file mode 100644 index 3e92446dd0..0000000000 --- a/src/mem/slicc/ast/PeekStatementAST.cc +++ /dev/null @@ -1,115 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PeekStatementAST.C - * - * Description: See PeekStatementAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/PeekStatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/VarExprAST.hh" - -PeekStatementAST::PeekStatementAST(VarExprAST* queue_name_ptr, - TypeAST* type_ptr, - StatementListAST* statementlist_ptr, - string method) - : StatementAST() -{ - m_queue_name_ptr = queue_name_ptr; - m_type_ptr = type_ptr; - m_statementlist_ptr = statementlist_ptr; - m_method = method; -} - -PeekStatementAST::~PeekStatementAST() -{ - delete m_queue_name_ptr; - delete m_type_ptr; - delete m_statementlist_ptr; -} - -void PeekStatementAST::generate(string& code, Type* return_type_ptr) const -{ - code += indent_str() + "{\n"; // Start scope - inc_indent(); - g_sym_table.pushFrame(); - - Type* msg_type_ptr = m_type_ptr->lookupType(); - - // Add new local var to symbol table - g_sym_table.newSym(new Var("in_msg", getLocation(), msg_type_ptr, "(*in_msg_ptr)", getPairs())); - - // Check the queue type - m_queue_name_ptr->assertType("InPort"); - - // Declare the new "in_msg_ptr" variable - code += indent_str() + "const " + msg_type_ptr->cIdent() + "* in_msg_ptr;\n"; // Declare message - // code += indent_str() + "in_msg_ptr = static_castcIdent() + "*>("; - code += "(" + m_queue_name_ptr->getVar()->getCode() + ")"; - code += "."; - code += m_method; - code += "());\n"; - - code += indent_str() + "assert(in_msg_ptr != NULL);\n"; // Check the cast result - - if(CHECK_INVALID_RESOURCE_STALLS) { - // Declare the "in_buffer_rank" variable - code += indent_str() + "int in_buffer_rank = "; // Declare message - code += "(" + m_queue_name_ptr->getVar()->getCode() + ")"; - code += ".getPriority();\n"; - } - - m_statementlist_ptr->generate(code, return_type_ptr); // The other statements - dec_indent(); - g_sym_table.popFrame(); - code += indent_str() + "}\n"; // End scope -} - -void PeekStatementAST::findResources(Map& resource_list) const -{ - m_statementlist_ptr->findResources(resource_list); -} - -void PeekStatementAST::print(ostream& out) const -{ - out << "[PeekStatementAST: " << m_method - << " queue_name: " << *m_queue_name_ptr - << " type: " << m_type_ptr->toString() - << " " << *m_statementlist_ptr - << "]"; -} diff --git a/src/mem/slicc/ast/PeekStatementAST.hh b/src/mem/slicc/ast/PeekStatementAST.hh deleted file mode 100644 index e8c65ce4f8..0000000000 --- a/src/mem/slicc/ast/PeekStatementAST.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PeekStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef PEEKSTATEMENTAST_H -#define PEEKSTATEMENTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" - -class StatementListAST; -class TypeAST; -class VarExprAST; - -class PeekStatementAST : public StatementAST { -public: - // Constructors - PeekStatementAST(VarExprAST* queue_name_ptr, - TypeAST* type_ptr, - StatementListAST* statementlist_ptr, - string method); - // Destructor - ~PeekStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - PeekStatementAST(const PeekStatementAST& obj); - PeekStatementAST& operator=(const PeekStatementAST& obj); - - // Data Members (m_ prefix) - VarExprAST* m_queue_name_ptr; - TypeAST* m_type_ptr; - StatementListAST* m_statementlist_ptr; - string m_method; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const PeekStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const PeekStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //PEEKSTATEMENTAST_H diff --git a/src/mem/slicc/ast/PeekStatementAST.py b/src/mem/slicc/ast/PeekStatementAST.py new file mode 100644 index 0000000000..5186bf0d5c --- /dev/null +++ b/src/mem/slicc/ast/PeekStatementAST.py @@ -0,0 +1,73 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST +from slicc.symbols import Var + +class PeekStatementAST(StatementAST): + def __init__(self, slicc, queue_name, type_ast, statements, method): + super(PeekStatementAST, self).__init__(slicc) + + self.queue_name = queue_name + self.type_ast = type_ast + self.statements = statements + self.method = method + + def __repr__(self): + return "[PeekStatementAST: %r queue_name: %r type: %r %r]" % \ + (self.method, self.queue_name, self.type_ast, self.statements) + + def generate(self, code, return_type): + self.symtab.pushFrame() + + msg_type = self.type_ast.type + + # Add new local var to symbol table + var = Var(self.symtab, "in_msg", self.location, msg_type, "(*in_msg_ptr)", + self.pairs) + self.symtab.newSymbol(var) + + # Check the queue type + self.queue_name.assertType("InPort") + + # Declare the new "in_msg_ptr" variable + mtid = msg_type.ident + qcode = self.queue_name.var.code + code(''' +{ + const $mtid* in_msg_ptr; + in_msg_ptr = dynamic_cast(($qcode).${{self.method}}()); + assert(in_msg_ptr != NULL); +''') + + # The other statements + self.statements.generate(code, return_type) + self.symtab.popFrame() + code("}") + + def findResources(self, resources): + self.statements.findResources(resources) diff --git a/src/mem/slicc/ast/ReturnStatementAST.cc b/src/mem/slicc/ast/ReturnStatementAST.cc deleted file mode 100644 index 8ec937c870..0000000000 --- a/src/mem/slicc/ast/ReturnStatementAST.cc +++ /dev/null @@ -1,79 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ReturnStatementAST.C - * - * Description: See ReturnStatementAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/ReturnStatementAST.hh" - -ReturnStatementAST::ReturnStatementAST(ExprAST* expr_ptr) - : StatementAST() -{ - m_expr_ptr = expr_ptr; -} - -ReturnStatementAST::~ReturnStatementAST() -{ - delete m_expr_ptr; -} - -void ReturnStatementAST::generate(string& code, Type* return_type_ptr) const -{ - code += indent_str(); - code += "return "; - Type* actual_type_ptr = m_expr_ptr->generate(code); - code += ";\n"; - - // Is return valid here? - if (return_type_ptr == NULL) { - error("Invalid 'return' statement"); - } - - // The return type must match the return_type_ptr - if (return_type_ptr != actual_type_ptr) { - m_expr_ptr->error("Return type miss-match, expected return type is '" + return_type_ptr->toString() + - "', actual is '" + actual_type_ptr->toString() + "'"); - } -} - -void ReturnStatementAST::findResources(Map& resource_list) const -{ - m_expr_ptr->findResources(resource_list); -} - -void ReturnStatementAST::print(ostream& out) const -{ - out << "[ReturnStatementAST: " << *m_expr_ptr << "]"; -} diff --git a/src/mem/slicc/ast/ReturnStatementAST.hh b/src/mem/slicc/ast/ReturnStatementAST.hh deleted file mode 100644 index 1fa1b36d69..0000000000 --- a/src/mem/slicc/ast/ReturnStatementAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * ReturnStatementAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef ReturnStatementAST_H -#define ReturnStatementAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - -class ReturnStatementAST : public StatementAST { -public: - // Constructors - ReturnStatementAST(ExprAST* expr_ptr); - - // Destructor - ~ReturnStatementAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - ReturnStatementAST(const ReturnStatementAST& obj); - ReturnStatementAST& operator=(const ReturnStatementAST& obj); - - // Data Members (m_ prefix) - ExprAST* m_expr_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const ReturnStatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const ReturnStatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //ReturnStatementAST_H diff --git a/src/mem/slicc/ast/ReturnStatementAST.py b/src/mem/slicc/ast/ReturnStatementAST.py new file mode 100644 index 0000000000..1d08a7234e --- /dev/null +++ b/src/mem/slicc/ast/ReturnStatementAST.py @@ -0,0 +1,54 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST + +class ReturnStatementAST(StatementAST): + def __init__(self, slicc, expr_ast): + super(ReturnStatementAST, self).__init__(slicc) + + self.expr_ast = expr_ast + + def __repr__(self): + return "[ReturnStatementAST: %r]" % self.expr_ast + + def generate(self, code, return_type): + actual_type, ecode = self.expr_ast.inline(True) + code('return $ecode;') + + # Is return valid here? + if return_type is None: + error("Invalid 'return' statement") + + # The return type must match + if return_type != actual_type: + self.expr_ast.error("Return type miss-match, expected return " + + "type is '%s', actual is '%s'", + return_type, actual_type) + + def findResources(self, resources): + self.expr_ast.findResources(resources) diff --git a/src/mem/slicc/ast/StatementAST.cc b/src/mem/slicc/ast/StatementAST.cc deleted file mode 100644 index 35627722ac..0000000000 --- a/src/mem/slicc/ast/StatementAST.cc +++ /dev/null @@ -1,60 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * StatementAST.C - * - * Description: See StatementAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/StatementAST.hh" - -static int indentation_depth = 1; - -void inc_indent() -{ - indentation_depth++; -} - -void dec_indent() -{ - indentation_depth--; -} - -string indent_str() -{ - string temp; - for(int i=0; i pairs) : AST(pairs) {} - - // Destructor - //~StatementAST(); - - // Public Methods - virtual void generate(string& code, Type* return_type_ptr) const = 0; - virtual void findResources(Map& resource_list) const { } - - //void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - //StatementAST(const StatementAST& obj); - //StatementAST& operator=(const StatementAST& obj); - - // Data Members (m_ prefix) - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const StatementAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const StatementAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //STATEMENTAST_H diff --git a/src/mem/slicc/ast/StatementAST.py b/src/mem/slicc/ast/StatementAST.py new file mode 100644 index 0000000000..017b2b1ede --- /dev/null +++ b/src/mem/slicc/ast/StatementAST.py @@ -0,0 +1,34 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class StatementAST(AST): + def __init__(self, slicc, pairs=None): + super(StatementAST, self).__init__(slicc, pairs) + + def findResources(self, resources): + pass diff --git a/src/mem/slicc/ast/StatementListAST.cc b/src/mem/slicc/ast/StatementListAST.cc deleted file mode 100644 index 0f5817f7ce..0000000000 --- a/src/mem/slicc/ast/StatementListAST.cc +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * StatementListAST.C - * - * Description: See StatementListAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/StatementListAST.hh" - -StatementListAST::StatementListAST(Vector* vec_ptr) - : AST() -{ - assert(vec_ptr != NULL); - m_vec_ptr = vec_ptr; -} - -// Singleton constructor. -StatementListAST::StatementListAST(StatementAST* statement_ptr) - : AST() -{ - assert(statement_ptr != NULL); - m_vec_ptr = new Vector; - m_vec_ptr->insertAtTop(statement_ptr); -} - -StatementListAST::~StatementListAST() -{ - int size = m_vec_ptr->size(); - for(int i=0; isize(); - for(int i=0; igenerate(code, return_type_ptr); - } -} - -void StatementListAST::findResources(Map& resource_list) const -{ - int size = m_vec_ptr->size(); - for(int i=0; ifindResources(resource_list); - } -} - -void StatementListAST::print(ostream& out) const -{ - assert(m_vec_ptr != NULL); - out << "[StatementListAST: " << *m_vec_ptr << "]"; -} diff --git a/src/mem/slicc/ast/StatementListAST.hh b/src/mem/slicc/ast/StatementListAST.hh deleted file mode 100644 index 831e2481a2..0000000000 --- a/src/mem/slicc/ast/StatementListAST.hh +++ /dev/null @@ -1,85 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * StatementListAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef STATEMENTLISTAST_H -#define STATEMENTLISTAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" -#include "mem/slicc/ast/StatementAST.hh" -class Var; - -class StatementListAST : public AST { -public: - // Constructors - StatementListAST(Vector* vec_ptr); - StatementListAST(StatementAST* statement_ptr); - - // Destructor - ~StatementListAST(); - - // Public Methods - void generate(string& code, Type* return_type_ptr) const; - void findResources(Map& resource_list) const; - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - StatementListAST(const StatementListAST& obj); - StatementListAST& operator=(const StatementListAST& obj); - - // Data Members (m_ prefix) - Vector* m_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const StatementListAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const StatementListAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //STATEMENTLISTAST_H diff --git a/src/mem/slicc/ast/StatementListAST.py b/src/mem/slicc/ast/StatementListAST.py new file mode 100644 index 0000000000..1475c5c977 --- /dev/null +++ b/src/mem/slicc/ast/StatementListAST.py @@ -0,0 +1,46 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class StatementListAST(AST): + def __init__(self, slicc, statements): + super(StatementListAST, self).__init__(slicc) + if not isinstance(statements, (list, tuple)): + statements = [ statements ] + self.statements = statements + + def __repr__(self): + return "[StatementListAST: %r]" % self.statements + + def generate(self, code, return_type): + for statement in self.statements: + statement.generate(code, return_type) + + def findResources(self, resources): + for statement in self.statements: + statement.findResources(resources) diff --git a/src/mem/slicc/ast/TransitionDeclAST.cc b/src/mem/slicc/ast/TransitionDeclAST.cc deleted file mode 100644 index 66b7ca132c..0000000000 --- a/src/mem/slicc/ast/TransitionDeclAST.cc +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TransitionDeclAST.C - * - * Description: See TransitionDeclAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/TransitionDeclAST.hh" -#include "mem/slicc/symbols/Transition.hh" - -TransitionDeclAST::TransitionDeclAST(Vector* state_list_ptr, - Vector* event_list_ptr, - string* next_state_ptr, - PairListAST* pairs_ptr, - Vector* action_list_ptr) - : DeclAST(pairs_ptr) -{ - m_state_list_ptr = state_list_ptr; - m_event_list_ptr = event_list_ptr; - m_next_state_ptr = next_state_ptr; - m_action_list_ptr = action_list_ptr; -} - -TransitionDeclAST::~TransitionDeclAST() -{ - delete m_state_list_ptr; - delete m_event_list_ptr; - delete m_next_state_ptr; - delete m_action_list_ptr; -} - -void TransitionDeclAST::generate() -{ - Vector& states = *m_state_list_ptr; - Vector& events = *m_event_list_ptr; - - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (machine_ptr == NULL) { - error("Transition declaration not part of a machine."); - } else if (m_next_state_ptr == NULL) { - for (int i=0; iaddTransition(new Transition(states[i], events[j], states[i], *m_action_list_ptr, getLocation(), getPairs())); - } - } - } else { - for (int i=0; iaddTransition(new Transition(states[i], events[j], *m_next_state_ptr, *m_action_list_ptr, getLocation(), getPairs())); - } - } - } -} - -void TransitionDeclAST::print(ostream& out) const -{ - out << "[TransitionDecl: ]"; -} diff --git a/src/mem/slicc/ast/TransitionDeclAST.hh b/src/mem/slicc/ast/TransitionDeclAST.hh deleted file mode 100644 index f07f0a3c2e..0000000000 --- a/src/mem/slicc/ast/TransitionDeclAST.hh +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TransistionDeclAST.hh - * - * Description: - * - * $Id: TransitionDeclAST.hh,v 3.2 2003/07/10 18:08:07 milo Exp $ - * - */ - -#ifndef TransitionDeclAST_H -#define TransitionDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" - -class TransitionDeclAST : public DeclAST { -public: - // Constructors - TransitionDeclAST(Vector* state_list_ptr, - Vector* event_list_ptr, - string* next_state_ptr, - PairListAST* pairs_ptr, - Vector* action_list_ptr); - - // Destructor - ~TransitionDeclAST(); - - // Public Methods - void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - TransitionDeclAST(const TransitionDeclAST& obj); - TransitionDeclAST& operator=(const TransitionDeclAST& obj); - - // Data Members (m_ prefix) - Vector* m_state_list_ptr; - Vector* m_event_list_ptr; - string* m_next_state_ptr; - Vector* m_action_list_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TransitionDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TransitionDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TransitionDeclAST_H diff --git a/src/mem/slicc/ast/TransitionDeclAST.py b/src/mem/slicc/ast/TransitionDeclAST.py new file mode 100644 index 0000000000..ef745fd503 --- /dev/null +++ b/src/mem/slicc/ast/TransitionDeclAST.py @@ -0,0 +1,54 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols import Transition + +class TransitionDeclAST(DeclAST): + def __init__(self, slicc, states, events, next_state, pairs, actions): + super(TransitionDeclAST, self).__init__(slicc, pairs) + + self.states = states + self.events = events + self.next_state = next_state + self.actions = actions + + def __repr__(self): + return "[TransitionDecl: ]" + + def generate(self): + machine = self.symtab.state_machine + + if machine is None: + self.error("Transition declaration not part of a machine.") + + for state in self.states: + next_state = self.next_state or state + for event in self.events: + t = Transition(self.symtab, machine, state, event, next_state, + self.actions, self.location, self.pairs) + machine.addTransition(t) diff --git a/src/mem/slicc/ast/TypeAST.cc b/src/mem/slicc/ast/TypeAST.cc deleted file mode 100644 index 7590b4e7c8..0000000000 --- a/src/mem/slicc/ast/TypeAST.cc +++ /dev/null @@ -1,67 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeAST.C - * - * Description: See TypeAST.hh - * - * $Id: TypeAST.C,v 3.1 2003/03/22 15:15:16 xu Exp $ - * - */ - -#include "mem/slicc/ast/TypeAST.hh" - -TypeAST::TypeAST(string* ident_ptr) - : AST() -{ - m_ident_ptr = ident_ptr; -} - -TypeAST::~TypeAST() -{ - delete m_ident_ptr; - -} - -string TypeAST::toString() const -{ - return *m_ident_ptr; -} - -Type* TypeAST::lookupType() const -{ - Type* type_ptr = g_sym_table.getType(*m_ident_ptr); - if (type_ptr != NULL) { - return type_ptr; - } else { - error("Type '" + *m_ident_ptr + "' not declared."); - } - return NULL; // Not reached -} diff --git a/src/mem/slicc/ast/TypeAST.hh b/src/mem/slicc/ast/TypeAST.hh deleted file mode 100644 index f8e1fdc240..0000000000 --- a/src/mem/slicc/ast/TypeAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeAST.hh - * - * Description: - * - * $Id: TypeAST.hh,v 3.2 2003/03/22 15:15:17 xu Exp $ - * - */ - -#ifndef TYPEAST_H -#define TYPEAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/AST.hh" - -class TypeAST : public AST { -public: - // Constructors - TypeAST(string* ident_ptr); - - // Destructor - ~TypeAST(); - - // Public Methods - string toString() const; - Type* lookupType() const; - - virtual void print(ostream& out) const {} -private: - // Private Methods - - // Private copy constructor and assignment operator - TypeAST(const TypeAST& obj); - TypeAST& operator=(const TypeAST& obj); - - // Data Members (m_ prefix) - string* m_ident_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TYPEAST_H diff --git a/src/mem/slicc/ast/TypeAST.py b/src/mem/slicc/ast/TypeAST.py new file mode 100644 index 0000000000..209859b8d8 --- /dev/null +++ b/src/mem/slicc/ast/TypeAST.py @@ -0,0 +1,53 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +from slicc.symbols import Type + +class TypeAST(AST): + def __init__(self, slicc, ident): + super(TypeAST, self).__init__(slicc) + + self.ident = ident + + def __repr__(self): + return self.ident + + def __str__(self): + return self.ident + + @property + def type(self, assert_type=None): + type = self.symtab.find(self.ident, Type) + if not type: + self.error("Type '%s' not declared.", self) + + if assert_type is not None and type != assert_type: + self.error("Type '%s' is should be type '%s'", self, assert_type) + + return type diff --git a/src/mem/slicc/ast/TypeDeclAST.cc b/src/mem/slicc/ast/TypeDeclAST.cc deleted file mode 100644 index bbf2f8491c..0000000000 --- a/src/mem/slicc/ast/TypeDeclAST.cc +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeDeclAST.C - * - * Description: See TypeDeclAST.hh - * - * $Id: TypeDeclAST.C,v 3.1 2003/03/22 15:15:17 xu Exp $ - * - */ - -#include "mem/slicc/ast/TypeDeclAST.hh" -#include "mem/slicc/main.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -TypeDeclAST::TypeDeclAST(TypeAST* type_ast_ptr, - PairListAST* pairs_ptr, - Vector* field_vec_ptr) - : DeclAST(pairs_ptr) -{ - m_type_ast_ptr = type_ast_ptr; - m_field_vec_ptr = field_vec_ptr; -} - -TypeDeclAST::~TypeDeclAST() -{ - delete m_type_ast_ptr; - if (m_field_vec_ptr != NULL) { - int size = m_field_vec_ptr->size(); - for(int i=0; itoString(); - - // Make the new type - Type* new_type_ptr = new Type(id, getLocation(), getPairs(), - g_sym_table.getStateMachine()); - g_sym_table.newSym(new_type_ptr); - - // Add all of the fields of the type to it - if (m_field_vec_ptr != NULL) { - int size = m_field_vec_ptr->size(); - for(int i=0; igenerate(new_type_ptr); - } - } -} - -void TypeDeclAST::print(ostream& out) const -{ - out << "[TypeDecl: " << m_type_ast_ptr->toString() << "]"; -} diff --git a/src/mem/slicc/ast/TypeDeclAST.hh b/src/mem/slicc/ast/TypeDeclAST.hh deleted file mode 100644 index 8a72c0406d..0000000000 --- a/src/mem/slicc/ast/TypeDeclAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeDeclAST.hh - * - * Description: - * - * $Id: TypeDeclAST.hh,v 3.2 2003/03/17 01:55:28 xu Exp $ - * - */ - -#ifndef TypeDeclAST_H -#define TypeDeclAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclAST.hh" -#include "mem/slicc/ast/TypeAST.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" - -class TypeDeclAST : public DeclAST { -public: - // Constructors - TypeDeclAST(TypeAST* type_ast_ptr, - PairListAST* pairs_ptr, - Vector* field_vec_ptr); - - // Destructor - ~TypeDeclAST(); - - // Public Methods - virtual void generate(); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - TypeDeclAST(const TypeDeclAST& obj); - TypeDeclAST& operator=(const TypeDeclAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_type_ast_ptr; - Vector* m_field_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeDeclAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeDeclAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TypeDeclAST_H diff --git a/src/mem/slicc/ast/TypeDeclAST.py b/src/mem/slicc/ast/TypeDeclAST.py new file mode 100644 index 0000000000..d2cc04eff5 --- /dev/null +++ b/src/mem/slicc/ast/TypeDeclAST.py @@ -0,0 +1,62 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.DeclAST import DeclAST +from slicc.symbols.Type import Type + +class TypeDeclAST(DeclAST): + def __init__(self, slicc, type_ast, pairs, field_asts): + super(TypeDeclAST, self).__init__(slicc, pairs) + + self.type_ast = type_ast + self.field_asts = field_asts + + def __repr__(self): + return "[TypeDecl: %r]" % (self.type_ast) + + def files(self, hh, cc, parent=None): + if "external" in self: + return + + if parent: + ident = "%s_%s" % (parent, self.type_ast.ident) + else: + ident = self.type_ast.ident + hh.add("%s.hh" % ident) + cc.add("%s.cc" % ident) + + def generate(self): + ident = str(self.type_ast) + + # Make the new type + new_type = Type(self.symtab, ident, self.location, self.pairs, + self.state_machine) + self.symtab.newSymbol(new_type) + + # Add all of the fields of the type to it + for field in self.field_asts: + field.generate(new_type) diff --git a/src/mem/slicc/ast/TypeFieldAST.cc b/src/mem/slicc/ast/TypeFieldAST.cc deleted file mode 100644 index 5657d023c2..0000000000 --- a/src/mem/slicc/ast/TypeFieldAST.cc +++ /dev/null @@ -1,44 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldAST.C - * - * Description: See TypeFieldAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/TypeFieldAST.hh" - -TypeFieldAST::TypeFieldAST(PairListAST* pairs_ptr) - : AST(pairs_ptr->getPairs()) { -} - diff --git a/src/mem/slicc/ast/TypeFieldAST.hh b/src/mem/slicc/ast/TypeFieldAST.hh deleted file mode 100644 index 1443720477..0000000000 --- a/src/mem/slicc/ast/TypeFieldAST.hh +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef TypeFieldAST_H -#define TypeFieldAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/PairListAST.hh" -#include "mem/slicc/ast/ExprAST.hh" - -class TypeFieldAST : public AST { -public: - // Constructors - TypeFieldAST(PairListAST* pairs_ptr); - - // Destructor - virtual ~TypeFieldAST() {} - - // Public Methods - virtual void generate(Type *type_ptr) = 0; - virtual void print(ostream& out) const = 0; -private: - // Private Methods - - // Private copy constructor and assignment operator - // TypeFieldAST(const TypeFieldAST& obj); - // TypeFieldAST& operator=(const TypeFieldAST& obj); - - // Data Members (m_ prefix) -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeFieldAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeFieldAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TypeFieldAST_H diff --git a/src/mem/slicc/ast/TypeFieldAST.py b/src/mem/slicc/ast/TypeFieldAST.py new file mode 100644 index 0000000000..7dd4c74aa7 --- /dev/null +++ b/src/mem/slicc/ast/TypeFieldAST.py @@ -0,0 +1,32 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import AST + +class TypeFieldAST(AST): + def __init__(self, slicc, pairs): + super(TypeFieldAST, self).__init__(slicc, pairs) diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.cc b/src/mem/slicc/ast/TypeFieldEnumAST.cc deleted file mode 100644 index 1a02f7edd1..0000000000 --- a/src/mem/slicc/ast/TypeFieldEnumAST.cc +++ /dev/null @@ -1,82 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldEnumAST.C - * - * Description: See TypeFieldEnumAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/TypeFieldEnumAST.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Event.hh" - -TypeFieldEnumAST::TypeFieldEnumAST(string* field_id_ptr, - PairListAST* pairs_ptr) - : TypeFieldAST(pairs_ptr) -{ - m_field_id_ptr = field_id_ptr; - m_pairs_ptr = pairs_ptr; -} - -TypeFieldEnumAST::~TypeFieldEnumAST() -{ - delete m_field_id_ptr; -} - -void TypeFieldEnumAST::generate(Type *type_ptr) -{ - // Add enumeration - if (!type_ptr->enumAdd(*m_field_id_ptr, m_pairs_ptr->getPairs())) { - error("Duplicate enumeration: " + type_ptr->toString() + ":" + *m_field_id_ptr); - } - - // Fill machine info - StateMachine* machine_ptr = g_sym_table.getStateMachine(); - if (type_ptr->toString() == "State") { - if (machine_ptr == NULL) { - error("State declaration not part of a machine."); - } - machine_ptr->addState(new State(*m_field_id_ptr, getLocation(), getPairs())); - } - if (type_ptr->toString() == "Event") { - if (machine_ptr == NULL) { - error("Event declaration not part of a machine."); - } - machine_ptr->addEvent(new Event(*m_field_id_ptr, getLocation(), getPairs())); - } -} - -void TypeFieldEnumAST::print(ostream& out) const -{ - out << "[TypeFieldEnum: " << *m_field_id_ptr << "]"; -} diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.hh b/src/mem/slicc/ast/TypeFieldEnumAST.hh deleted file mode 100644 index cd02f03bbd..0000000000 --- a/src/mem/slicc/ast/TypeFieldEnumAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldEnumAST.hh - * - * Description: - * - * $Id: TypeFieldEnumAST.hh,v 3.2 2003/07/10 18:08:07 milo Exp $ - * - */ - -#ifndef TypeFieldEnumAST_H -#define TypeFieldEnumAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/PairListAST.hh" - -class TypeFieldEnumAST : public TypeFieldAST { -public: - // Constructors - TypeFieldEnumAST(string* field_id_ptr, - PairListAST* pairs_ptr); - - // Destructor - ~TypeFieldEnumAST(); - - // Public Methods - void generate(Type *type_ptr); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - TypeFieldEnumAST(const TypeFieldEnumAST& obj); - TypeFieldEnumAST& operator=(const TypeFieldEnumAST& obj); - - // Data Members (m_ prefix) - string* m_field_id_ptr; - PairListAST* m_pairs_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeFieldEnumAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeFieldEnumAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TypeFieldEnumAST_H diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.py b/src/mem/slicc/ast/TypeFieldEnumAST.py new file mode 100644 index 0000000000..d068666ad4 --- /dev/null +++ b/src/mem/slicc/ast/TypeFieldEnumAST.py @@ -0,0 +1,59 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.TypeFieldAST import TypeFieldAST +from slicc.symbols import Event, State + +class TypeFieldEnumAST(TypeFieldAST): + def __init__(self, slicc, field_id, pairs_ast): + super(TypeFieldEnumAST, self).__init__(slicc, pairs_ast) + + self.field_id = field_id + self.pairs_ast = pairs_ast + + def __repr__(self): + return "[TypeFieldEnum: %r]" % self.field_id + + def generate(self, type): + # Add enumeration + if not type.enumAdd(self.field_id, self.pairs_ast.pairs): + error("Duplicate enumeration: %s:%s" % (type, self.field_id)) + + # Fill machine info + machine = self.symtab.state_machine + + if str(type) == "State": + if not machine: + error("State declaration not part of a machine.") + s = State(self.symtab, self.field_id, self.location, self.pairs) + machine.addState(s) + + if str(type) == "Event": + if not machine: + error("Event declaration not part of a machine.") + e = Event(self.symtab, self.field_id, self.location, self.pairs) + machine.addEvent(e) diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.cc b/src/mem/slicc/ast/TypeFieldMemberAST.cc deleted file mode 100644 index 1fe0f6d4b4..0000000000 --- a/src/mem/slicc/ast/TypeFieldMemberAST.cc +++ /dev/null @@ -1,84 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldMemberAST.C - * - * Description: See TypeFieldMemberAST.hh - * - * $Id: TypeFieldMemberAST.C,v 3.1 2003/03/27 22:58:54 xu Exp $ - * - */ - -#include "mem/slicc/ast/TypeFieldMemberAST.hh" - -TypeFieldMemberAST::TypeFieldMemberAST(TypeAST* type_ast_ptr, - string* field_id_ptr, - PairListAST* pairs_ptr, - ExprAST* rvalue_ptr) - : TypeFieldAST(pairs_ptr) -{ - m_type_ast_ptr = type_ast_ptr; - m_field_id_ptr = field_id_ptr; - m_rvalue_ptr = rvalue_ptr; -} - -TypeFieldMemberAST::~TypeFieldMemberAST() -{ - delete m_type_ast_ptr; - delete m_field_id_ptr; - if(m_rvalue_ptr) delete m_rvalue_ptr; -} - -void TypeFieldMemberAST::generate(Type *type_ptr) -{ - // Lookup type - Type* field_type_ptr = m_type_ast_ptr->lookupType(); - - // check type if this is a initialization - string* init_code = NULL; - if(m_rvalue_ptr) { - init_code = new string(); - Type* rvalue_type_ptr = m_rvalue_ptr->generate(*init_code); - if(field_type_ptr != rvalue_type_ptr) { - error("Initialization type mismatch '" + field_type_ptr->toString() + "' and '" + rvalue_type_ptr->toString() + "'"); - } - } - - // Add data member to the parent type - if (!type_ptr->dataMemberAdd(*m_field_id_ptr, field_type_ptr, getPairs(), - init_code)) { - error("Duplicate data member: " + type_ptr->toString() + ":" + *m_field_id_ptr); - } -} - -void TypeFieldMemberAST::print(ostream& out) const -{ - out << "[TypeFieldMember: " << *m_field_id_ptr << "]"; -} diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.hh b/src/mem/slicc/ast/TypeFieldMemberAST.hh deleted file mode 100644 index 47355f3ac4..0000000000 --- a/src/mem/slicc/ast/TypeFieldMemberAST.hh +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldMemberAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef TypeFieldMemberAST_H -#define TypeFieldMemberAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/ast/StatementListAST.hh" -#include "mem/slicc/ast/PairListAST.hh" -#include "mem/slicc/ast/ExprAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class TypeFieldMemberAST : public TypeFieldAST { -public: - // Constructors - TypeFieldMemberAST(TypeAST* type_ast_ptr, - string* field_id_ptr, - PairListAST* pairs_ptr, - ExprAST* rvalue_ptr); - - // Destructor - ~TypeFieldMemberAST(); - - // Public Methods - void generate(Type *type_ptr); - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - TypeFieldMemberAST(const TypeFieldMemberAST& obj); - TypeFieldMemberAST& operator=(const TypeFieldMemberAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_type_ast_ptr; - string* m_field_id_ptr; - ExprAST* m_rvalue_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeFieldMemberAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeFieldMemberAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TypeFieldMemberAST_H diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.py b/src/mem/slicc/ast/TypeFieldMemberAST.py new file mode 100644 index 0000000000..285d5b6225 --- /dev/null +++ b/src/mem/slicc/ast/TypeFieldMemberAST.py @@ -0,0 +1,57 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.TypeFieldAST import TypeFieldAST + +class TypeFieldMemberAST(TypeFieldAST): + def __init__(self, slicc, type_ast, field_id, pairs, rvalue): + super(TypeFieldMemberAST, self).__init__(slicc, pairs) + + self.type_ast = type_ast + self.field_id = field_id + self.rvalue = rvalue + + def __repr__(self): + return "[TypeFieldMember: %r]" % self.field_id + + def generate(self, type): + # Lookup type + field_type = self.type_ast.type + + # check type if this is a initialization + init_code = "" + if self.rvalue: + rvalue_type,init_code = self.rvalue.inline(True) + if field_type != rvalue_type: + self.error("Initialization type mismatch '%s' and '%s'" % \ + (field_type, rvalue_type)) + + # Add data member to the parent type + if not type.dataMemberAdd(self.field_id, field_type, self.pairs, + init_code): + + error("Duplicate data member: %s:%s" % (type_ptr, field_id)) diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.cc b/src/mem/slicc/ast/TypeFieldMethodAST.cc deleted file mode 100644 index 03c528f87d..0000000000 --- a/src/mem/slicc/ast/TypeFieldMethodAST.cc +++ /dev/null @@ -1,81 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldMethodAST.C - * - * Description: See TypeFieldMethodAST.hh - * - * $Id: TypeFieldMethodAST.C,v 3.1 2003/07/10 18:08:07 milo Exp $ - * - */ - -#include "mem/slicc/ast/TypeFieldMethodAST.hh" - -TypeFieldMethodAST::TypeFieldMethodAST(TypeAST* return_type_ast_ptr, - string* ident_ptr, - Vector* type_ast_vec_ptr, - PairListAST* pairs_ptr) - : TypeFieldAST(pairs_ptr) -{ - m_return_type_ast_ptr = return_type_ast_ptr; - m_ident_ptr = ident_ptr; - m_type_ast_vec_ptr = type_ast_vec_ptr; -} - -TypeFieldMethodAST::~TypeFieldMethodAST() -{ - delete m_return_type_ast_ptr; - delete m_ident_ptr; - - int size = m_type_ast_vec_ptr->size(); - for(int i=0; ilookupType(); - - // Lookup parameter types - Vector type_vec; - int size = m_type_ast_vec_ptr->size(); - for(int i=0; ilookupType(); - type_vec.insertAtBottom(type_ptr); - } - - // Add method - if (!type_ptr->methodAdd(*m_ident_ptr, return_type_ptr, type_vec)) { // Return false on error - error("Duplicate method: " + type_ptr->toString() + ":" + *m_ident_ptr + "()"); - } -} diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.hh b/src/mem/slicc/ast/TypeFieldMethodAST.hh deleted file mode 100644 index 10d53ef808..0000000000 --- a/src/mem/slicc/ast/TypeFieldMethodAST.hh +++ /dev/null @@ -1,87 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * TypeFieldMethodAST.hh - * - * Description: - * - * $Id: TypeFieldMethodAST.hh,v 3.2 2003/07/10 18:08:07 milo Exp $ - * - */ - -#ifndef TYPEFIELDMETHODAST_H -#define TYPEFIELDMETHODAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/TypeFieldAST.hh" -#include "mem/slicc/ast/TypeAST.hh" - -class TypeFieldMethodAST : public TypeFieldAST { -public: - // Constructors - TypeFieldMethodAST(TypeAST* return_type_ast_ptr, - string* ident_ptr, - Vector* type_ast_vec_ptr, - PairListAST* pairs_ptr); - // Destructor - ~TypeFieldMethodAST(); - - // Public Methods - - void generate(Type *type_ptr); - void print(ostream& out) const {} -private: - // Private Methods - - // Private copy constructor and assignment operator - TypeFieldMethodAST(const TypeFieldMethodAST& obj); - TypeFieldMethodAST& operator=(const TypeFieldMethodAST& obj); - - // Data Members (m_ prefix) - TypeAST* m_return_type_ast_ptr; - string* m_ident_ptr; - Vector* m_type_ast_vec_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const TypeFieldMethodAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const TypeFieldMethodAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TYPEFIELDMETHODAST_H diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.py b/src/mem/slicc/ast/TypeFieldMethodAST.py new file mode 100644 index 0000000000..337b155972 --- /dev/null +++ b/src/mem/slicc/ast/TypeFieldMethodAST.py @@ -0,0 +1,50 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.TypeFieldAST import TypeFieldAST + +class TypeFieldMethodAST(TypeFieldAST): + def __init__(self, slicc, return_type_ast, ident, type_asts, pairs): + super(TypeFieldMethodAST, self).__init__(slicc, pairs) + + self.return_type_ast = return_type_ast + self.ident = ident + self.type_asts = type_asts + + def __repr__(self): + return "" + + def generate(self, type): + # Lookup return type + return_type = self.return_type_ast.type + + # Lookup parameter types + types = [ t.type for t in self.type_asts ] + + # Add method + if not type.methodAdd(self.ident, return_type, types): + error("Duplicate method: %s:%s()" % (type, self.ident)) diff --git a/src/mem/slicc/ast/VarExprAST.cc b/src/mem/slicc/ast/VarExprAST.cc deleted file mode 100644 index 13e2655408..0000000000 --- a/src/mem/slicc/ast/VarExprAST.cc +++ /dev/null @@ -1,76 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VarExprAST.C - * - * Description: See VarExprAST.hh - * - * $Id$ - * - */ - -#include "mem/slicc/ast/VarExprAST.hh" -#include "mem/slicc/ast/StatementAST.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -VarExprAST::~VarExprAST() -{ - delete m_var_ptr; -} - - -Var* VarExprAST::getVar() const -{ - string var = *m_var_ptr; - Var* var_ptr = g_sym_table.getVar(var); - if (var_ptr == NULL) { - error("Unrecognized variable: " + var); - } - return var_ptr; -} - -void VarExprAST::assertType(string type_ident) const -{ - Type* expected_type_ptr = g_sym_table.getType(type_ident); - if (expected_type_ptr == NULL) { - error("There must be a type '" + type_ident + "' declared in this scope"); - } - - if (getVar()->getType() != expected_type_ptr) { - error("Incorrect type: '" + getVar()->getIdent() + "' is expected to be type '" + expected_type_ptr->toString() + "'"); - } -} - -Type* VarExprAST::generate(string& code) const -{ - Var* var_ptr = getVar(); - code += var_ptr->getCode(); - return var_ptr->getType(); -} diff --git a/src/mem/slicc/ast/VarExprAST.hh b/src/mem/slicc/ast/VarExprAST.hh deleted file mode 100644 index ea32582a24..0000000000 --- a/src/mem/slicc/ast/VarExprAST.hh +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * VarExprAST.hh - * - * Description: - * - * $Id$ - * - */ - -#ifndef VAREXPRAST_H -#define VAREXPRAST_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/ExprAST.hh" -class Var; - -class VarExprAST : public ExprAST { -public: - // Constructors - VarExprAST(string* var_ptr) : ExprAST() { m_var_ptr = var_ptr; } - - // Destructor - ~VarExprAST(); - - // Public Methods - Type* generate(string& code) const; - void print(ostream& out) const { out << "[VarExprAST: " << *m_var_ptr << "]"; } - string getName() const { return *m_var_ptr; } - Var* getVar() const; - void assertType(string type_ident) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - VarExprAST(const VarExprAST& obj); - VarExprAST& operator=(const VarExprAST& obj); - - // Data Members (m_ prefix) - string* m_var_ptr; - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const VarExprAST& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const VarExprAST& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //VAREXPRAST_H diff --git a/src/mem/slicc/ast/VarExprAST.py b/src/mem/slicc/ast/VarExprAST.py new file mode 100644 index 0000000000..ac440bb687 --- /dev/null +++ b/src/mem/slicc/ast/VarExprAST.py @@ -0,0 +1,66 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Type, Var + +class VarExprAST(ExprAST): + def __init__(self, slicc, var): + super(VarExprAST, self).__init__(slicc) + self._var = var + + def __repr__(self): + return "[VarExprAST: %r]" % self._var + + @property + def name(self): + return str(self._var) + + @property + def var(self): + var = self.symtab.find(self._var, Var) + if not var: + self.error("Unrecognized variable: %s", self._var) + return var + + def assertType(self, type_ident): + expected_type = self.symtab.find(type_ident, Type) + + if not expected_type: + self.error("There must be a type '%s' declared in this scope", + type_ident) + + if self.var.type != expected_type: + self.error("Incorrect type: " + \ + "'%s' is expected to be type '%s' not '%s'", + self.var.ident, expected_type, self.var.type) + + def generate(self, code): + fix = code.nofix() + code("${{self.var.code}}") + code.fix(fix) + return self.var.type diff --git a/src/mem/slicc/ast/__init__.py b/src/mem/slicc/ast/__init__.py new file mode 100644 index 0000000000..de50cbd49c --- /dev/null +++ b/src/mem/slicc/ast/__init__.py @@ -0,0 +1,69 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.AST import * + +# actual ASTs +from slicc.ast.ActionDeclAST import * +from slicc.ast.AssignStatementAST import * +from slicc.ast.CheckAllocateStatementAST import * +from slicc.ast.CheckStopSlotsStatementAST import * +from slicc.ast.ChipComponentAccessAST import * +from slicc.ast.CopyHeadStatementAST import * +from slicc.ast.DeclAST import * +from slicc.ast.DeclListAST import * +from slicc.ast.EnqueueStatementAST import * +from slicc.ast.EnumDeclAST import * +from slicc.ast.EnumExprAST import * +from slicc.ast.ExprAST import * +from slicc.ast.ExprStatementAST import * +from slicc.ast.FormalParamAST import * +from slicc.ast.FuncCallExprAST import * +from slicc.ast.FuncDeclAST import * +from slicc.ast.IfStatementAST import * +from slicc.ast.InPortDeclAST import * +from slicc.ast.InfixOperatorExprAST import * +from slicc.ast.LiteralExprAST import * +from slicc.ast.MachineAST import * +from slicc.ast.MemberExprAST import * +from slicc.ast.MethodCallExprAST import * +from slicc.ast.NewExprAST import * +from slicc.ast.ObjDeclAST import * +from slicc.ast.OutPortDeclAST import * +from slicc.ast.PairAST import * +from slicc.ast.PairListAST import * +from slicc.ast.PeekStatementAST import * +from slicc.ast.ReturnStatementAST import * +from slicc.ast.StatementAST import * +from slicc.ast.StatementListAST import * +from slicc.ast.TransitionDeclAST import * +from slicc.ast.TypeAST import * +from slicc.ast.TypeDeclAST import * +from slicc.ast.TypeFieldAST import * +from slicc.ast.TypeFieldEnumAST import * +from slicc.ast.TypeFieldMemberAST import * +from slicc.ast.TypeFieldMethodAST import * +from slicc.ast.VarExprAST import * diff --git a/src/mem/slicc/generate/__init__.py b/src/mem/slicc/generate/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mem/slicc/generate/dot.py b/src/mem/slicc/generate/dot.py new file mode 100644 index 0000000000..762658983c --- /dev/null +++ b/src/mem/slicc/generate/dot.py @@ -0,0 +1,42 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util.code_formatter import code_formatter + +def printDotty(sm, code): + code('digraph ${{sm.getIdent()}} {') + code.indent() + for t in sm.transitions: + # Don't print ignored transitions + if t.getActionShorthands() in ("--", "z"): + continue + + code('${{t.getStateShorthand()}} -> ${{t.getNextStateShorthand()}') + code(' [label="${{t.getEventShorthand()}}/${{t.getActionShorthands()}}"') + code.dedent() + code('}') + diff --git a/src/mem/slicc/generate/html.py b/src/mem/slicc/generate/html.py new file mode 100644 index 0000000000..53252ce3c6 --- /dev/null +++ b/src/mem/slicc/generate/html.py @@ -0,0 +1,80 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util.code_formatter import code_formatter + +def createSymbol(symbol, title): + code = code_formatter() + code(''' +$title: +${{formatShorthand(symbol.short)}} - ${{symbol.desc}}''') + return code + +def formatShorthand(short): + munged_shorthand = "" + mode_is_normal = True + + # -- Walk over the string, processing superscript directives + gen = enumerate(short) + for i,c in gen: + if c == '!': + # -- Reached logical end of shorthand name + break + elif c == '_': + munged_shorthand += " " + elif c == '^': + # -- Process super/subscript formatting + mode_is_normal = not mode_is_normal + if mode_is_normal: + # -- Back to normal mode + munged_shorthand += "" + else: + # -- Going to superscript mode + munged_shorthand += "" + elif c == '\\': + # -- Process Symbol character set + if i + 1 < len(short): + # -- Proceed to next char. Yes I know that changing + # the loop var is ugly! + i,c = gen.next() + munged_shorthand += "" + munged_shorthand += c + munged_shorthand += "" + else: + # -- FIXME: Add line number info later + panic("Encountered a `\\` without anything following it!") + else: + # -- Pass on un-munged + munged_shorthand += c + + # -- Do any other munging + if not mode_is_normal: + # -- Back to normal mode + munged_shorthand += "" + + return munged_shorthand + diff --git a/src/mem/slicc/generate/tex.py b/src/mem/slicc/generate/tex.py new file mode 100644 index 0000000000..97c63ebc60 --- /dev/null +++ b/src/mem/slicc/generate/tex.py @@ -0,0 +1,71 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util.code_formatter import code_formatter + +class tex_formatter(code_formatter): + braced = "<>" + double_braced = "<<>>" + +def printTexTable(sm, code): + tex = tex_formatter() + tex(r''' +%& latex +\documentclass[12pt]{article} +\usepackage{graphics} +\begin{document} +\begin{tabular}{|l||$<<"l" * len(sm.events)>>|} \hline +''') + + for event in sm.events: + code(r" & \rotatebox{90}{$<>}") + tex(r'\\ \hline \hline') + + for state in sm.states: + state_str = state.short + for event in sm.events: + state_str += ' & ' + trans = sm.get_transition(state, event) + if trans: + actions = trans.getActionShorthands() + # FIXME: should compare index, not the string + if trans.getNextStateShorthand() != state.short: + nextState = trans.getNextStateShorthand() + else: + nextState = "" + state_str += actions + if nextState and actions: + state_str += '/' + state_str += nextState + tex(r'$0 \\', state_str) + tex(r''' +\hline +\end{tabular} +\end{document} +''') + + code.append(tex) diff --git a/src/mem/slicc/generator/fileio.cc b/src/mem/slicc/generator/fileio.cc deleted file mode 100644 index 15eccd3cad..0000000000 --- a/src/mem/slicc/generator/fileio.cc +++ /dev/null @@ -1,66 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * fileio.C - * - * Description: See fileio.hh - * - * $Id: fileio.C,v 3.3 2003/07/10 18:08:08 milo Exp $ - * - * */ - -#include "mem/slicc/generator/fileio.hh" - -void conditionally_write_file(string filename, ostringstream& sstr) -{ - ofstream out; - ifstream in; - string input_file; - - // Read in the file if it exists - in.open(filename.c_str()); - char c; - while (in.get(c)) { - input_file += c; - } - in.close(); - - // Check to see if the file is the same as what we want to write - if (input_file != sstr.str()) { - cout << " Overwriting file: " << filename << endl; - // Overwrite the old file with the new file - out.open(filename.c_str()); - out << sstr.str(); - out.close(); - } else { - //cout << " Keeping old file: " << filename << endl; - } -} - diff --git a/src/mem/slicc/generator/fileio.hh b/src/mem/slicc/generator/fileio.hh deleted file mode 100644 index 81b7306bc2..0000000000 --- a/src/mem/slicc/generator/fileio.hh +++ /dev/null @@ -1,46 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * fileio.hh - * - * Description: - * - * $Id: fileio.hh,v 3.2 2003/02/24 20:54:25 xu Exp $ - * - * */ - -#ifndef FILEIO_H -#define FILEIO_H - -#include "mem/slicc/slicc_global.hh" - -void conditionally_write_file(string filename, ostringstream& sstr); - -#endif //FILEIO_H diff --git a/src/mem/slicc/generator/html_gen.cc b/src/mem/slicc/generator/html_gen.cc deleted file mode 100644 index 2d35dccb69..0000000000 --- a/src/mem/slicc/generator/html_gen.cc +++ /dev/null @@ -1,125 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * html_gen.C - * - * Description: See html_gen.hh - * - * $Id: html_gen.C,v 3.4 2004/01/31 20:46:50 milo Exp $ - * - * */ - -#include "mem/slicc/generator/html_gen.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/symbols/SymbolTable.hh" - -string formatHTMLShorthand(const string shorthand); - - -void createHTMLSymbol(const Symbol& sym, string title, ostream& out) -{ - out << "" << endl; - out << title << ": " << endl; - out << formatHTMLShorthand(sym.getShorthand()) << " - "; - out << sym.getDescription(); - out << "" << endl; -} - -void createHTMLindex(string title, ostream& out) -{ - out << "" << endl; - out << "" << endl; - out << "" << title << "" << endl; - out << "" << endl; - out << "" << endl; - Vector machine_vec = g_sym_table.getStateMachines(); - if (machine_vec.size() > 1) { - string machine = machine_vec[0]->getIdent(); - out << " " << endl; - } else { - out << " " << endl; - } - - out << " " << endl; - out << "" << endl; - out << "" << endl; -} - -string formatHTMLShorthand(const string shorthand) -{ - string munged_shorthand = ""; - bool mode_is_normal = true; - - // -- Walk over the string, processing superscript directives - for(unsigned int i = 0; i < shorthand.length(); i++) { - if(shorthand[i] == '!') { - // -- Reached logical end of shorthand name - break; - } else if( shorthand[i] == '_') { - munged_shorthand += " "; - } else if( shorthand[i] == '^') { - // -- Process super/subscript formatting - mode_is_normal = !mode_is_normal; - if(mode_is_normal) { - // -- Back to normal mode - munged_shorthand += ""; - } else { - // -- Going to superscript mode - munged_shorthand += ""; - } - } else if(shorthand[i] == '\\') { - // -- Process Symbol character set - if((i + 1) < shorthand.length()) { - i++; // -- Proceed to next char. Yes I know that changing the loop var is ugly! - munged_shorthand += ""; - munged_shorthand += shorthand[i]; - munged_shorthand += ""; - } else { - // -- FIXME: Add line number info later - cerr << "Encountered a `\\` without anything following it!" << endl; - exit( -1 ); - } - } else { - // -- Pass on un-munged - munged_shorthand += shorthand[i]; - } - } // -- end for all characters in shorthand - - // -- Do any other munging - if(!mode_is_normal) { - // -- Back to normal mode - munged_shorthand += ""; - } - - // -- Return the formatted shorthand name - return munged_shorthand; -} - - diff --git a/src/mem/slicc/generator/html_gen.hh b/src/mem/slicc/generator/html_gen.hh deleted file mode 100644 index 6b1f8ea92e..0000000000 --- a/src/mem/slicc/generator/html_gen.hh +++ /dev/null @@ -1,49 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * html_gen.hh - * - * Description: - * - * $Id: html_gen.hh,v 3.1 2001/12/12 01:00:35 milo Exp $ - * - * */ - -#ifndef HTML_GEN_H -#define HTML_GEN_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -string formatHTMLShorthand(const string shorthand); -void createHTMLindex(string title, ostream& out); -void createHTMLSymbol(const Symbol& sym, string title, ostream& out); - -#endif //HTML_GEN_H diff --git a/src/mem/slicc/generator/mif_gen.cc b/src/mem/slicc/generator/mif_gen.cc deleted file mode 100644 index 2dca149b42..0000000000 --- a/src/mem/slicc/generator/mif_gen.cc +++ /dev/null @@ -1,1718 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/generator/mif_gen.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Event.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/slicc/symbols/Transition.hh" - -// -- Helper functions -string formatShorthand(const string shorthand); -string formatCellRuling(const string shorthand); - -void printStateTableMIF(const StateMachine& sm, ostream& out) -{ - const string mif_prolog1 = -" # Generated by Multifacet MIF Mungers Inc\n\ -\n\ - \n\ - \n\ -\n\ - # \n\ - \n\ -\n\ - \n\ - \n\ - \n\ - \n\ -\n\ - \n\ - \n\ - \n\ - > # end of TblColumnH\n\ - \n\ - > # end of TblColumnBody\n\ - \n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - \n\ - \n\ - \n\ - > # end of TblColumnH\n\ - \n\ - > # end of TblColumnBody\n\ - \n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - > # end of TblFormat\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - \n\ - \n\ - \n\ - \n\ - > # end of Marker\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ - > # end of TblH\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - \n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ -"; - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - out << mif_prolog1; - out << formatShorthand( sm.getShorthand() ); - out << " states"; - out << mif_prolog2; - - for( int i = 0; i < sm.numStates(); i++ ) - { - out << row_before_state; - out << formatShorthand( sm.getState( i ).getShorthand() ); - out << row_between_state_desc; - out << sm.getState( i ).getDescription(); - out << row_after_desc; - } - - out << mif_epilog; -} - - -void printEventTableMIF(const StateMachine& sm, ostream& out) -{ - const string mif_prolog1 = -" # Generated by Multifacet MIF Mungers Inc\n\ -\n\ - \n\ - \n\ -\n\ - # \n\ - \n\ -\n\ - \n\ - \n\ - \n\ - \n\ -\n\ - \n\ - \n\ - \n\ - > # end of TblColumnH\n\ - \n\ - > # end of TblColumnBody\n\ - \n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - \n\ - \n\ - \n\ - > # end of TblColumnH\n\ - \n\ - > # end of TblColumnBody\n\ - \n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - > # end of TblFormat\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - \n\ - \n\ - \n\ - \n\ - > # end of Marker\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ - > # end of TblH\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - \n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ -"; - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - out << mif_prolog1; - out << formatShorthand( sm.getShorthand() ); - out << " events"; - out << mif_prolog2; - - for( int i = 0; i < sm.numEvents(); i++ ) - { - out << row_before_event; - out << formatShorthand( sm.getEvent( i ).getShorthand() ); - out << row_between_event_desc; - out << sm.getEvent( i ).getDescription(); - out << row_after_desc; - } - - out << mif_epilog; -} - - -void printActionTableMIF(const StateMachine& sm, ostream& out) -{ - const string mif_prolog1 = -" # Generated by Multifacet MIF Mungers Inc\n\ -\n\ - \n\ - \n\ -\n\ - # \n\ - \n\ -\n\ - \n\ - \n\ - \n\ - \n\ -\n\ - \n\ - \n\ - \n\ - > # end of TblColumnH\n\ - \n\ - > # end of TblColumnBody\n\ - \n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - \n\ - \n\ - \n\ - > # end of TblColumnH\n\ - \n\ - > # end of TblColumnBody\n\ - \n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - > # end of TblFormat\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - \n\ - \n\ - \n\ - \n\ - > # end of Marker\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ - > # end of TblH\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - \n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ -"; - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - out << mif_prolog1; - out << formatShorthand( sm.getShorthand() ); - out << " actions"; - out << mif_prolog2; - - for( int i = 0; i < sm.numActions(); i++ ) - { - out << row_before_action; - out << formatShorthand( sm.getAction( i ).getShorthand() ); - out << row_between_action_desc; - out << sm.getAction( i ).getDescription(); - out << row_after_desc; - } - - out << mif_epilog; -} - - -void printTransitionTableMIF(const StateMachine& sm, ostream& out) -{ - const string mif_prolog = -" # Generated by Multifacet MIF Mungers Inc\n\ -\n\ - \n\ - \n\ -\n\ - # \n\ - \n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ -"; - - const string tbl_fmt_before_col_num = -" \n\ - \n\ - \n\ - > # end of TblColumnH\n\ - \n\ - > # end of TblColumnBody\n\ - \n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ -"; - - const string tbl_fmt_before_num_cols = -" > # end of TblFormat\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - \n\ - \n\ - \n\ - \n\ - > # end of Marker\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - \n\ - "; - - const string tbl_before_each_header = -" \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ -"; - - const string before_first_row = -" > # end of Row\n\ - > # end of TblH\n\ -\n\ - \n\ - "; - - const string row_cell_before_ruling = -" \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ -"; - - const string row_empty_cell = -" \n\ - \n\ - \n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ -"; - - const string row_after_last_cell = -" > # end of Row\n\ -"; - - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - int i, j, num_rows, num_cols; - string row_ruling; - string col_ruling; - - num_rows = sm.numStates(); - num_cols = sm.numEvents() + 1; - - // -- Prolog - out << mif_prolog; - - // -- Table format (for each column) - for( i = 0; i < num_cols; i++ ) - { - out << tbl_fmt_before_col_num; - out << i; - out << tbl_fmt_after_col_num; - } - - // -- Spell out width of each column - - // -- FIXME: make following constants into parameters - const float total_table_width = 7.5; // -- Total page width = 7.5" (portrait mode) - const float min_col_width = 0.35; // -- Min col width (for legibility) - const float max_col_width = 0.75; // -- Max col width (for aesthetics) - float column_width; - - // -- Calculate column width and clamp it within a range - column_width = total_table_width / num_cols; - column_width = ((column_width < min_col_width) - ? min_col_width - : ((column_width > max_col_width) - ? max_col_width - : column_width)); - - out << tbl_fmt_before_num_cols; - out << num_cols; - for( i = 0; i < num_cols; i++ ) - { - out << tbl_fmt_each_col_width_begin << column_width << tbl_fmt_each_col_width_end; - } - - // -- Column headers - out << tbl_before_first_header1; - out << formatShorthand( sm.getShorthand() ); - out << " transitions"; - out << tbl_before_first_header2; - - out << tbl_before_each_header; - out << "State"; - out << tbl_after_each_header; - - for( i = 0; i < sm.numEvents(); i++ ) - { - out << tbl_before_each_rot_header; - out << formatShorthand( sm.getEvent(i).getShorthand() ); - out << tbl_after_each_header; - } - out << before_first_row; - - - // -- Body of table - for( i = 0; i < num_rows; i++ ) - { - // -- Each row - out << row_before_first_cell; - - // -- Figure out ruling - if (sm.getState(i).existPair("format")) { - row_ruling = formatCellRuling( sm.getState(i).lookupPair("format")); - } else { - row_ruling = ""; - } - - // -- First column = state - out << row_cell_before_ruling; - out << row_ruling; - out << row_cell_before_contents; - out << formatShorthand( sm.getState(i).getShorthand() ); - out << row_cell_after_contents; - - // -- One column for each event - for( j = 0; j < sm.numEvents(); j++ ) - { - const Transition* trans_ptr = sm.getTransPtr( i, j ); - - // -- Figure out ruling - if (sm.getEvent(j).existPair("format")) { - col_ruling = formatCellRuling(sm.getEvent(j).lookupPair("format")); - } else { - col_ruling = ""; - } - - out << row_cell_before_ruling; - out << row_ruling; - out << col_ruling; - - if( trans_ptr != NULL ) - { - string actions; - string nextState; - - // -- Get the actions - actions = formatShorthand( trans_ptr->getActionShorthands() ); - - // -- Get the next state - // FIXME: should compare index, not the string - if (trans_ptr->getNextStateShorthand() != - sm.getState(i).getShorthand() ) - { - nextState = formatShorthand( trans_ptr->getNextStateShorthand() ); - } else - { - nextState = ""; - } - - // -- Print out "actions/next-state" - out << row_cell_before_contents; - out << actions; - if ((nextState.length() != 0) && (actions.length() != 0)) { - out << "/"; - } - out << nextState; - out << row_cell_after_contents; - } - else - { - out << row_empty_cell; - } - - } - - out << row_after_last_cell; - } - - // -- Epilog - out << mif_epilog; - -} -/* -void printTBETableMIF(const StateMachine& sm, const Vector& fields, ostream& out) -{ - const string mif_prolog1 = -" # Generated by Multifacet MIF Mungers Inc\n\ -\n\ - \n\ - \n\ -\n\ - # # \n\ - \n\ -\n\ - \n\ - \n\ - \n\ - \n\ -\n\ - \n\ - \n\ - \n\ - > # end of TblColumnH\n\ - \n\ - > # end of TblColumnBody\n\ - \n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - \n\ - \n\ - \n\ - > # end of TblColumnH\n\ - \n\ - > # end of TblColumnBody\n\ - \n\ - > # end of TblColumnF\n\ - > # end of TblColumn\n\ - > # end of TblFormat\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - > # end of Pgf\n\ - \n\ - \n\ - \n\ - \n\ - > # end of Marker\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of TblTitleContent\n\ - > # end of TblTitle\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ - > # end of TblH\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - > # end of PgfFont\n\ - >\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - \n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ - > # end of CellContent\n\ - > # end of Cell\n\ - > # end of Row\n\ -"; - - const string mif_epilog = -" > # end of TblBody\n\ - > # end of Tbl\n\ -> # end of Tbls\n\ -\n\ - \n\ - > # end of ParaLine\n\ - > # end of Para\n\ -\n\ -# End of MIFFile\n\ -"; - - out << mif_prolog1; - out << sm.getShorthand(); - out << " TBE"; - out << mif_prolog2; - - for( int i = 0; i < fields.size(); i++ ) { - out << row_before_state; - out << formatShorthand(fields[i].getShorthand()); - out << row_between_state_desc; - out << fields[i].getDescription(); - out << row_after_desc; - } - - out << mif_epilog; -} -*/ -// -- -// -- Helper function to do some shorthand formatting (kludge before we -// -- get the tuple attributes into the state machine language. -// -- Current convention: -// -- - each `_' indicates a toggle between normal mode and superscript -// -- - each escaped (using `\') character indicates a letter formatted -// -- using the Symbol character set. \a = alpha, \b = beta, \c = chi etc. -// -- See the FrameMaker character sets manual in the Online Manuals. -// -- - a `!' indicates extra stuff at the end which can be ignored (used -// -- for determining cell ruling and so on) -// -- -string formatShorthand(const string shorthand) -{ - string munged_shorthand = ""; - bool mode_is_normal = true; - const string mif_superscript = "'> > bottom of this row is ruled -// -- - `r' => right of this column is ruled -// -- -string formatCellRuling( const string shorthand) -{ - for( unsigned int i = 0; i < shorthand.length(); i++ ) - { - if( shorthand[i] == '!' ) - { - // -- OK, found beginning of ruling information - for( unsigned int j = i+1; j < shorthand.length(); j++ ) - { - if( shorthand[j] == 'b') - { - // -- Rule the bottom - return "\n"; - } - else if( shorthand[j] == 'r') - { - // -- Rule the bottom - return "\n"; - } - - } - - // -- No ruling directives recognized, return default ruling - return ""; - } - - } - - // -- No ruling information found, return default ruling - return ""; -} diff --git a/src/mem/slicc/generator/mif_gen.hh b/src/mem/slicc/generator/mif_gen.hh deleted file mode 100644 index 6da75f748e..0000000000 --- a/src/mem/slicc/generator/mif_gen.hh +++ /dev/null @@ -1,45 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id: mif_gen.hh,v 3.1 2001/12/12 01:00:35 milo Exp $ - * - */ - -#ifndef MIF_GEN_H -#define MIF_GEN_H - -#include "mem/slicc/symbols/StateMachine.hh" - -void printStateTableMIF(const StateMachine& sm, ostream& out); -void printEventTableMIF(const StateMachine& sm, ostream& out); -void printActionTableMIF(const StateMachine& sm, ostream& out); -void printTransitionTableMIF(const StateMachine& sm, ostream& out); - -#endif //MIF_GEN_H diff --git a/src/mem/slicc/main.cc b/src/mem/slicc/main.cc deleted file mode 100644 index 294925ee15..0000000000 --- a/src/mem/slicc/main.cc +++ /dev/null @@ -1,246 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#include "mem/slicc/main.hh" -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/generator/mif_gen.hh" -#include "mem/slicc/generator/html_gen.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/ast/DeclListAST.hh" -#include "mem/slicc/symbols/Type.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/symbols/Event.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/slicc/symbols/Transition.hh" - -// -- Main conversion functions - -void printDotty(const StateMachine& sm, ostream& out); -void printTexTable(const StateMachine& sm, ostream& out); - -DeclListAST* g_decl_list_ptr; -DeclListAST* parse(string filename); - -int main(int argc, char *argv[]) -{ - cerr << "SLICC v0.3" << endl; - - if (argc < 5) { - cerr << " Usage: generator.exec files ... " << endl; - exit(1); - } - - // The path we should place the generated code - string code_path(argv[1]); - code_path += "/"; - - // The path we should place the generated html - string html_path(argv[2]); - html_path += "/"; - - string ident(argv[3]); - - string html_generate(argv[4]); - - Vector decl_list_vec; - - // Parse - cerr << "Parsing..." << endl; - for(int i=5; ifindMachines(); - } - - // Generate Code - cerr << "Generator pass 2..." << endl; - for(int i=0; igenerate(); - delete decl_list_ptr; - } - - // Generate C/C++ files - cerr << "Writing C files..." << endl; - - { - // Generate the name of the protocol - ostringstream sstr; - sstr << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__< "; - out << t.getNextStateShorthand() << "[label=\""; - out << t.getEventShorthand() << "/" - << t.getActionShorthands() << "\"]" << endl; - } - } - out << "}" << endl; -} - -void printTexTable(const StateMachine& sm, ostream& out) -{ - const Transition* trans_ptr; - int stateIndex, eventIndex; - string actions; - string nextState; - - out << "%& latex" << endl; - out << "\\documentclass[12pt]{article}" << endl; - out << "\\usepackage{graphics}" << endl; - out << "\\begin{document}" << endl; - // out << "{\\large" << endl; - out << "\\begin{tabular}{|l||"; - for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) { - out << "l"; - } - out << "|} \\hline" << endl; - - for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) { - out << " & \\rotatebox{90}{"; - out << sm.getEvent(eventIndex).getShorthand(); - out << "}"; - } - out << "\\\\ \\hline \\hline" << endl; - - for(stateIndex=0; stateIndex < sm.numStates(); stateIndex++) { - out << sm.getState(stateIndex).getShorthand(); - for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) { - out << " & "; - trans_ptr = sm.getTransPtr(stateIndex, eventIndex); - if (trans_ptr == NULL) { - } else { - actions = trans_ptr->getActionShorthands(); - // FIXME: should compare index, not the string - if (trans_ptr->getNextStateShorthand() != - sm.getState(stateIndex).getShorthand() ) { - nextState = trans_ptr->getNextStateShorthand(); - } else { - nextState = ""; - } - - out << actions; - if ((nextState.length() != 0) && (actions.length() != 0)) { - out << "/"; - } - out << nextState; - } - } - out << "\\\\" << endl; - } - out << "\\hline" << endl; - out << "\\end{tabular}" << endl; - // out << "}" << endl; - out << "\\end{document}" << endl; -} - diff --git a/src/mem/slicc/main.hh b/src/mem/slicc/main.hh deleted file mode 100644 index a10dcca532..0000000000 --- a/src/mem/slicc/main.hh +++ /dev/null @@ -1,48 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * main.hh - * - * Description: - * - * $Id: main.hh,v 3.2 2003/03/17 01:50:01 xu Exp $ - * - * */ - -#ifndef MAIN_H -#define MAIN_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/ast/DeclListAST.hh" -#include "mem/gems_common/Map.hh" - -extern DeclListAST* g_decl_list_ptr; - -#endif //MAIN_H diff --git a/src/mem/slicc/main.py b/src/mem/slicc/main.py new file mode 100644 index 0000000000..0bc2ef37a6 --- /dev/null +++ b/src/mem/slicc/main.py @@ -0,0 +1,108 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys + +from slicc.parser import SLICC + +usage="%prog [options] ... " +version="%prog v0.4" +brief_copyright=''' +Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +Copyright (c) 2009 The Hewlett-Packard Development Company +All Rights Reserved. +''' + +def nprint(format, *args): + pass + +def eprint(format, *args): + if args: + format = format % args + + print >>sys.stderr, format + +def main(args=None): + import optparse + + parser = optparse.OptionParser(usage=usage, version=version, + description=brief_copyright) + parser.add_option("-d", "--debug", default=False, action="store_true", + help="Turn on PLY debugging") + parser.add_option("-C", "--code-path", default="generated", + help="Path where C++ code output code goes") + parser.add_option("-H", "--html-path", + help="Path where html output goes") + parser.add_option("-F", "--print-files", + help="Print files that SLICC will generate") + parser.add_option("-q", "--quiet", + help="don't print messages") + opts,files = parser.parse_args(args=args) + + if len(files) < 1: + parser.print_help() + sys.exit(2) + + output = nprint if opts.quiet else eprint + + output("SLICC v0.4") + slicc = SLICC(debug=opts.debug) + + output("Parsing...") + for filename in slicc.load(files, verbose=True): + output(" %s", filename) + + if opts.print_files: + hh, cc = slicc.files() + hh = sorted(hh) + cc = sorted(cc) + print 'Headers:' + for i in hh: + print ' %s' % i + + print 'Sources:' + for i in cc: + print ' %s' % i + else: + output("Generator pass 1...") + slicc.findMachines() + + output("Generator pass 2...") + slicc.generate() + + output("Generating C++ files...") + slicc.writeCodeFiles(opts.code_path) + + if opts.html_path: + nprint("Writing HTML files...") + slicc.writeHTMLFiles(opts.html_path) + + eprint("SLICC is Done.") + +if __name__ == "__main__": + main() diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py new file mode 100644 index 0000000000..0e5ccc885c --- /dev/null +++ b/src/mem/slicc/parser.py @@ -0,0 +1,669 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Nathan Binkert + +import os.path +import re +import sys + +from m5.util.grammar import Grammar, TokenError, ParseError + +import slicc.ast as ast +import slicc.util as util +from slicc.symbols import SymbolTable + +def read_slicc(sources): + if not isinstance(sources, (list,tuple)): + sources = [ sources ] + + for source in sources: + for sm_file in file(source, "r"): + sm_file = sm_file.strip() + if not sm_file: + continue + if sm_file.startswith("#"): + continue + yield sm_file + +class SLICC(Grammar): + def __init__(self, **kwargs): + super(SLICC, self).__init__(**kwargs) + self.decl_list_vec = [] + self.current_file = None + self.symtab = SymbolTable() + + def parse(self, filename): + self.current_file = filename + f = file(filename, 'r') + text = f.read() + try: + decl_list = super(SLICC, self).parse(text) + except (TokenError, ParseError), e: + sys.exit("%s: %s:%d" % (e, filename, e.token.lineno)) + self.decl_list_vec.append(decl_list) + self.current_file = None + + def _load(self, *filenames): + filenames = list(filenames) + while filenames: + f = filenames.pop(0) + if isinstance(f, (list, tuple)): + filenames[0:0] = list(f) + continue + + yield f + if f.endswith(".slicc"): + dirname,basename = os.path.split(f) + filenames[0:0] = [ os.path.join(dirname, x) \ + for x in read_slicc(f)] + else: + assert f.endswith(".sm") + self.parse(f) + + def load(self, *filenames, **kwargs): + verbose = kwargs.pop("verbose", False) + if kwargs: + raise TypeError + + gen = self._load(*filenames) + if verbose: + return gen + else: + # Run out the generator if we don't want the verbosity + for foo in gen: + pass + + def findMachines(self): + for decl_list in self.decl_list_vec: + decl_list.findMachines() + + def generate(self): + for decl_list in self.decl_list_vec: + decl_list.generate() + + def writeCodeFiles(self, code_path): + util.makeDir(code_path) + self.symtab.writeCodeFiles(code_path) + + def writeHTMLFiles(self, code_path): + util.makeDir(code_path) + self.symtab.writeHTMLFiles(code_path) + + def files(self): + cc = set([ + 'ControllerFactory.cc', + 'MachineType.cc']) + + hh = set([ + 'ControllerFactory.hh', + 'MachineType.hh', + 'Types.hh' ]) + + for decl_list in self.decl_list_vec: + decl_list.files(hh, cc) + + return hh, cc + + t_ignore = '\t ' + + # C or C++ comment (ignore) + def t_c_comment(self, t): + r'/\*(.|\n)*?\*/' + t.lexer.lineno += t.value.count('\n') + + def t_cpp_comment(self, t): + r'//.*' + + # Define a rule so we can track line numbers + def t_newline(self, t): + r'\n+' + t.lexer.lineno += len(t.value) + + reserved = { + 'global' : 'GLOBAL', + 'machine' : 'MACHINE', + 'in_port' : 'IN_PORT', + 'out_port' : 'OUT_PORT', + 'action' : 'ACTION', + 'transition' : 'TRANS', + 'structure' : 'STRUCT', + 'external_type' : 'EXTERN_TYPE', + 'enumeration' : 'ENUM', + 'peek' : 'PEEK', + 'enqueue' : 'ENQUEUE', + 'copy_head' : 'COPY_HEAD', + 'check_allocate' : 'CHECK_ALLOCATE', + 'check_stop_slots' : 'CHECK_STOP_SLOTS', + 'if' : 'IF', + 'else' : 'ELSE', + 'return' : 'RETURN', + 'THIS' : 'THIS', + 'CHIP' : 'CHIP', + 'void' : 'VOID', + 'new' : 'NEW', + } + + literals = ':[]{}(),=' + + tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE', + 'LEFTSHIFT', 'RIGHTSHIFT', + 'NOT', 'AND', 'OR', + 'PLUS', 'DASH', 'STAR', 'SLASH', + 'DOUBLE_COLON', 'SEMI', + 'ASSIGN', 'DOT', + 'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ] + tokens += reserved.values() + + t_EQ = r'==' + t_NE = r'!=' + t_LT = r'<' + t_GT = r'>' + t_LE = r'<=' + t_GE = r'>=' + t_LEFTSHIFT = r'<<' + t_RIGHTSHIFT = r'>>' + t_NOT = r'!' + t_AND = r'&&' + t_OR = r'\|\|' + t_PLUS = r'\+' + t_DASH = r'-' + t_STAR = r'\*' + t_SLASH = r'/' + t_DOUBLE_COLON = r'::' + t_SEMI = r';' + t_ASSIGN = r':=' + t_DOT = r'\.' + + precedence = ( + ('left', 'AND', 'OR'), + ('left', 'EQ', 'NE'), + ('left', 'LT', 'GT', 'LE', 'GE'), + ('left', 'RIGHTSHIFT', 'LEFTSHIFT'), + ('left', 'PLUS', 'DASH'), + ('left', 'STAR', 'SLASH'), + ('right', 'NOT', 'UMINUS'), + ) + + def t_IDENT(self, t): + r'[a-zA-Z_][a-zA-Z_0-9]*' + if t.value == 'true': + t.type = 'LIT_BOOL' + t.value = True + return t + + if t.value == 'false': + t.type = 'LIT_BOOL' + t.value = False + return t + + # Check for reserved words + t.type = self.reserved.get(t.value, 'IDENT') + return t + + def t_FLOATNUMBER(self, t): + '[0-9]+[.][0-9]+' + try: + t.value = float(t.value) + except ValueError: + raise TokenError("Illegal float", t) + return t + + def t_NUMBER(self, t): + r'[0-9]+' + try: + t.value = int(t.value) + except ValueError: + raise TokenError("Illegal number", t) + return t + + def t_STRING1(self, t): + r'\"[^"\n]*\"' + t.type = 'STRING' + t.value = t.value[1:-1] + return t + + def t_STRING2(self, t): + r"\'[^'\n]*\'" + t.type = 'STRING' + t.value = t.value[1:-1] + return t + + def p_file(self, p): + "file : decls" + p[0] = p[1] + + def p_empty(self, p): + "empty :" + + def p_decls(self, p): + "decls : declsx" + p[0] = ast.DeclListAST(self, p[1]) + + def p_declsx__list(self, p): + "declsx : decl declsx" + p[0] = [ p[1] ] + p[2] + + def p_declsx__none(self, p): + "declsx : empty" + p[0] = [] + + def p_decl__machine(self, p): + "decl : MACHINE '(' ident pairs ')' ':' params '{' decls '}'" + p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9]) + + def p_decl__action(self, p): + "decl : ACTION '(' ident pairs ')' statements" + p[0] = ast.ActionDeclAST(self, p[3], p[4], p[6]) + + def p_decl__in_port(self, p): + "decl : IN_PORT '(' ident ',' type ',' var pairs ')' statements" + p[0] = ast.InPortDeclAST(self, p[3], p[5], p[7], p[8], p[10]) + + def p_decl__out_port(self, p): + "decl : OUT_PORT '(' ident ',' type ',' var pairs ')' SEMI" + p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8]) + + def p_decl__trans0(self, p): + "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents" + p[0] = ast.TransitionDeclAST(self, p[3], p[5], p[7], p[8], p[10]) + + def p_decl__trans1(self, p): + "decl : TRANS '(' idents ',' idents pairs ')' idents" + p[0] = ast.TransitionDeclAST(self, p[3], p[5], None, p[6], p[8]) + + def p_decl__extern0(self, p): + "decl : EXTERN_TYPE '(' type pairs ')' SEMI" + p[4]["external"] = "yes" + p[0] = ast.TypeDeclAST(self, p[3], p[4], []) + + def p_decl__extern1(self, p): + "decl : EXTERN_TYPE '(' type pairs ')' '{' type_methods '}'" + p[4]["external"] = "yes" + p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) + + def p_decl__global(self, p): + "decl : GLOBAL '(' type pairs ')' '{' type_members '}'" + p[4]["global"] = "yes" + p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) + + def p_decl__struct(self, p): + "decl : STRUCT '(' type pairs ')' '{' type_members '}'" + p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) + + def p_decl__enum(self, p): + "decl : ENUM '(' type pairs ')' '{' type_enums '}'" + p[4]["enumeration"] = "yes" + p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7]) + + def p_decl__object(self, p): + "decl : type ident pairs SEMI" + p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3]) + + def p_decl__func_decl(self, p): + """decl : void ident '(' params ')' pairs SEMI + | type ident '(' params ')' pairs SEMI""" + p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None) + + def p_decl__func_def(self, p): + """decl : void ident '(' params ')' pairs statements + | type ident '(' params ')' pairs statements""" + p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7]) + + # Type fields + def p_type_members__list(self, p): + "type_members : type_member type_members" + p[0] = [ p[1] ] + p[2] + + def p_type_members__empty(self, p): + "type_members : empty" + p[0] = [] + + def p_type_member__1(self, p): + "type_member : type ident pairs SEMI" + p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], p[3], None) + + def p_type_member__2(self, p): + "type_member : type ident ASSIGN expr SEMI" + p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], + ast.PairListAST(self), p[4]) + + # Methods + def p_type_methods__list(self, p): + "type_methods : type_method type_methods" + p[0] = [ p[1] ] + p[2] + + def p_type_methods(self, p): + "type_methods : empty" + p[0] = [] + + def p_type_method(self, p): + "type_method : type_or_void ident '(' types ')' pairs SEMI" + p[0] = ast.TypeFieldMethodAST(self, p[1], p[2], p[4], p[6]) + + # Enum fields + def p_type_enums__list(self, p): + "type_enums : type_enum type_enums" + p[0] = [ p[1] ] + p[2] + + def p_type_enums__empty(self, p): + "type_enums : empty" + p[0] = [] + + def p_type_enum(self, p): + "type_enum : ident pairs SEMI" + p[0] = ast.TypeFieldEnumAST(self, p[1], p[2]) + + # Type + def p_types__multiple(self, p): + "types : type ',' types" + p[0] = [ p[1] ] + p[3] + + def p_types__one(self, p): + "types : type" + p[0] = [ p[1] ] + + def p_types__empty(self, p): + "types : empty" + p[0] = [] + + def p_type(self, p): + "type : ident" + p[0] = ast.TypeAST(self, p[1]) + + def p_void(self, p): + "void : VOID" + p[0] = ast.TypeAST(self, p[1]) + + def p_type_or_void(self, p): + """type_or_void : type + | void""" + p[0] = p[1] + + # Formal Param + def p_params__many(self, p): + "params : param ',' params" + p[0] = [ p[1] ] + p[3] + + def p_params__one(self, p): + "params : param" + p[0] = [ p[1] ] + + def p_params__none(self, p): + "params : empty" + p[0] = [] + + def p_param(self, p): + "param : type ident" + p[0] = ast.FormalParamAST(self, p[1], p[2]) + + # Idents and lists + def p_idents__braced(self, p): + "idents : '{' identx '}'" + p[0] = p[2] + + def p_idents__bare(self, p): + "idents : ident" + p[0] = [ p[1] ] + + def p_identx__multiple_1(self, p): + """identx : ident SEMI identx + | ident ',' identx""" + p[0] = [ p[1] ] + p[3] + + def p_identx__multiple_2(self, p): + "identx : ident identx" + p[0] = [ p[1] ] + p[2] + + def p_identx__single(self, p): + "identx : empty" + p[0] = [ ] + + def p_ident(self, p): + "ident : IDENT" + p[0] = p[1] + + # Pair and pair lists + def p_pairs__list(self, p): + "pairs : ',' pairsx" + p[0] = p[2] + + def p_pairs__empty(self, p): + "pairs : empty" + p[0] = ast.PairListAST(self) + + def p_pairsx__many(self, p): + "pairsx : pair ',' pairsx" + p[0] = p[3] + p[0].addPair(p[1]) + + def p_pairsx__one(self, p): + "pairsx : pair" + p[0] = ast.PairListAST(self) + p[0].addPair(p[1]) + + def p_pair__assign(self, p): + """pair : ident '=' STRING + | ident '=' ident""" + p[0] = ast.PairAST(self, p[1], p[3]) + + def p_pair__literal(self, p): + "pair : STRING" + p[0] = ast.PairAST(self, "short", p[1]) + + # Below are the rules for action descriptions + def p_statements__inner(self, p): + "statements : '{' statements_inner '}'" + p[0] = ast.StatementListAST(self, p[2]) + + def p_statements__none(self, p): + "statements : '{' '}'" + p[0] = ast.StatementListAST(self, []) + + def p_statements_inner__many(self, p): + "statements_inner : statement statements_inner" + p[0] = [ p[1] ] + p[2] + + def p_statements_inner__one(self, p): + "statements_inner : statement" + p[0] = [ p[1] ] + + def p_exprs__multiple(self, p): + "exprs : expr ',' exprs" + p[0] = [ p[1] ] + p[3] + + def p_exprs__one(self, p): + "exprs : expr" + p[0] = [ p[1] ] + + def p_exprs__empty(self, p): + "exprs : empty""" + p[0] = [] + + def p_statement__expression(self, p): + "statement : expr SEMI" + p[0] = ast.ExprStatementAST(self, p[1]) + + def p_statement__assign(self, p): + "statement : expr ASSIGN expr SEMI" + p[0] = ast.AssignStatementAST(self, p[1], p[3]) + + def p_statement__enqueue(self, p): + "statement : ENQUEUE '(' var ',' type pairs ')' statements" + p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[6], p[8]) + + def p_statement__peek(self, p): + "statement : PEEK '(' var ',' type ')' statements" + p[0] = ast.PeekStatementAST(self, p[3], p[5], p[7], "peek") + + def p_statement__copy_head(self, p): + "statement : COPY_HEAD '(' var ',' var pairs ')' SEMI" + p[0] = ast.CopyHeadStatementAST(self, p[3], p[5], p[6]) + + def p_statement__check_allocate(self, p): + "statement : CHECK_ALLOCATE '(' var ')' SEMI" + p[0] = ast.CheckAllocateStatementAST(self, p[3]) + + def p_statement__check_stop(self, p): + "statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI" + p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7]) + + def p_statement__return(self, p): + "statement : RETURN expr SEMI" + p[0] = ast.ReturnStatementAST(self, p[2]) + + def p_statement__if(self, p): + "statement : if_statement" + p[0] = p[1] + + def p_if_statement__if(self, p): + "if_statement : IF '(' expr ')' statements" + p[0] = ast.IfStatementAST(self, p[3], p[5], None) + + def p_if_statement__if_else(self, p): + "if_statement : IF '(' expr ')' statements ELSE statements" + p[0] = ast.IfStatementAST(self, p[3], p[5], p[7]) + + def p_statement__if_else_if(self, p): + "if_statement : IF '(' expr ')' statements ELSE if_statement" + p[0] = ast.IfStatementAST(self, p[3], p[5], + ast.StatementListAST(self, p[7])) + + def p_expr__var(self, p): + "aexpr : var" + p[0] = p[1] + + def p_expr__literal(self, p): + "aexpr : literal" + p[0] = p[1] + + def p_expr__enumeration(self, p): + "aexpr : enumeration" + p[0] = p[1] + + def p_expr__func_call(self, p): + "aexpr : ident '(' exprs ')'" + p[0] = ast.FuncCallExprAST(self, p[1], p[3]) + + def p_expr__new(self, p): + "aexpr : NEW type" + p[0] = ast.NewExprAST(self, p[2]) + + # globally access a local chip component and call a method + def p_expr__local_chip_method(self, p): + "aexpr : THIS DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'" + p[0] = ast.LocalChipMethodAST(self, p[3], p[5], p[8], p[10], p[12]) + + # globally access a local chip component and access a data member + def p_expr__local_chip_member(self, p): + "aexpr : THIS DOT var '[' expr ']' DOT var DOT field" + p[0] = ast.LocalChipMemberAST(self, p[3], p[5], p[8], p[10]) + + # globally access a specified chip component and call a method + def p_expr__specified_chip_method(self, p): + "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'" + p[0] = ast.SpecifiedChipMethodAST(self, p[3], p[6], p[8], p[11], p[13], + p[15]) + + # globally access a specified chip component and access a data member + def p_expr__specified_chip_member(self, p): + "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field" + p[0] = ast.SpecifiedChipMemberAST(self, p[3], p[6], p[8], p[11], p[13]) + + def p_expr__member(self, p): + "aexpr : aexpr DOT ident" + p[0] = ast.MemberExprAST(self, p[1], p[3]) + + def p_expr__member_method_call(self, p): + "aexpr : aexpr DOT ident '(' exprs ')'" + p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5]) + + def p_expr__member_method_call_lookup(self, p): + "aexpr : aexpr '[' exprs ']'" + p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3]) + + def p_expr__class_method_call(self, p): + "aexpr : type DOUBLE_COLON ident '(' exprs ')'" + p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5]) + + def p_expr__aexpr(self, p): + "expr : aexpr" + p[0] = p[1] + + def p_expr__binary_op(self, p): + """expr : expr STAR expr + | expr SLASH expr + | expr PLUS expr + | expr DASH expr + | expr LT expr + | expr GT expr + | expr LE expr + | expr GE expr + | expr EQ expr + | expr NE expr + | expr AND expr + | expr OR expr + | expr RIGHTSHIFT expr + | expr LEFTSHIFT expr""" + p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3]) + + # FIXME - unary not + def p_expr__unary_op(self, p): + """expr : NOT expr + | DASH expr %prec UMINUS""" + p[0] = PrefixOperatorExpr(p[1], p[2]) + + def p_expr__parens(self, p): + "aexpr : '(' expr ')'" + p[0] = p[2] + + def p_literal__string(self, p): + "literal : STRING" + p[0] = ast.LiteralExprAST(self, p[1], "string") + + def p_literal__number(self, p): + "literal : NUMBER" + p[0] = ast.LiteralExprAST(self, p[1], "int") + + def p_literal__float(self, p): + "literal : FLOATNUMBER" + p[0] = ast.LiteralExprAST(self, p[1], "int") + + def p_literal__bool(self, p): + "literal : LIT_BOOL" + p[0] = ast.LiteralExprAST(self, p[1], "bool") + + def p_enumeration(self, p): + "enumeration : ident ':' ident" + p[0] = ast.EnumExprAST(self, ast.TypeAST(self, p[1]), p[3]) + + def p_var(self, p): + "var : ident" + p[0] = ast.VarExprAST(self, p[1]) + + def p_field(self, p): + "field : ident" + p[0] = p[1] diff --git a/src/mem/slicc/parser/lexer.ll b/src/mem/slicc/parser/lexer.ll deleted file mode 100644 index b2d36855b4..0000000000 --- a/src/mem/slicc/parser/lexer.ll +++ /dev/null @@ -1,125 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -%{ - -#include -#include "mem/slicc/ast/ASTs.hh" -#include "parser.hh" -#include - -extern "C" int yylex(); -extern "C" void yyerror(); -extern "C" int yywrap() -{ - return 1; -} - -%} -%x CMNT -%x IMBEDED -%% - -[\t ]+ /* Ignore whitespace */ -[\n] { g_line_number++; } -"//".*[\n] { g_line_number++; } /* C++ style comments */ - -"/*" BEGIN CMNT; -. ; -\n { g_line_number++; } -"*/" { BEGIN INITIAL; } - -true { yylval.str_ptr = new string(yytext); return LIT_BOOL; } -false { yylval.str_ptr = new string(yytext); return LIT_BOOL; } -global { return GLOBAL_DECL; } -machine { return MACHINE_DECL; } -in_port { return IN_PORT_DECL; } -out_port { return OUT_PORT_DECL; } -action { return ACTION_DECL; } -transition { return TRANSITION_DECL; } -structure { return STRUCT_DECL; } -external_type { return EXTERN_TYPE_DECL; } -enumeration { return ENUM_DECL; } -peek { return PEEK; } -enqueue { return ENQUEUE; } -copy_head { return COPY_HEAD; } -check_allocate { return CHECK_ALLOCATE; } -check_stop_slots { return CHECK_STOP_SLOTS; } -if { return IF; } -else { return ELSE; } -return { return RETURN; } -THIS { return THIS; } -CHIP { return CHIP; } -void { yylval.str_ptr = new string(yytext); return VOID; } -new { return NEW; } - -== { yylval.str_ptr = new string(yytext); return EQ; } -!= { yylval.str_ptr = new string(yytext); return NE; } -[<] { yylval.str_ptr = new string(yytext); return '<'; } -[>] { yylval.str_ptr = new string(yytext); return '>'; } -[<][<] { yylval.str_ptr = new string(yytext); return LEFTSHIFT; } -[>][>] { yylval.str_ptr = new string(yytext); return RIGHTSHIFT; } -[<][=] { yylval.str_ptr = new string(yytext); return LE; } -[>][=] { yylval.str_ptr = new string(yytext); return GE; } -[!] { yylval.str_ptr = new string(yytext); return NOT; } -[&][&] { yylval.str_ptr = new string(yytext); return AND; } -[|][|] { yylval.str_ptr = new string(yytext); return OR; } -[+] { yylval.str_ptr = new string(yytext); return PLUS; } -[-] { yylval.str_ptr = new string(yytext); return DASH; } -[*] { yylval.str_ptr = new string(yytext); return STAR; } -[/] { yylval.str_ptr = new string(yytext); return SLASH; } -:: { return DOUBLE_COLON; } -[:] { return ':'; } -[;] { return SEMICOLON; } -[[] { return '['; } -[]] { return ']'; } -[{] { return '{'; } -[}] { return '}'; } -[(] { return '('; } -[)] { return ')'; } -[,] { return ','; } -[=] { return '='; } -:= { return ASSIGN; } -[.] { return DOT; } - -[0-9]*[.][0-9]* { yylval.str_ptr = new string(yytext); return FLOATNUMBER; } -[0-9]* { yylval.str_ptr = new string(yytext); return NUMBER; } - -[a-zA-Z_][a-zA-Z_0-9]{0,50} { yylval.str_ptr = new string(yytext); return IDENT; } -\"[^"\n]*\" { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; } -\'[^'\n]*\' { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; } - -. { return OTHER; } /* Need so that we handle all characters */ - -%% - diff --git a/src/mem/slicc/parser/parser.py b/src/mem/slicc/parser/parser.py deleted file mode 100644 index 7fecfd2730..0000000000 --- a/src/mem/slicc/parser/parser.py +++ /dev/null @@ -1,563 +0,0 @@ -# Copyright (c) 2009 The Hewlett-Packard Development Company -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Nathan Binkert - -from ply import lex, yacc -import re - -t_ignore = '\t ' - -# C or C++ comment (ignore) -def t_c_comment(t): - r'/\*(.|\n)*?\*/' - t.lexer.lineno += t.value.count('\n') - -def t_cpp_comment(t): - r'//.*' - pass - -# Define a rule so we can track line numbers -def t_newline(t): - r'\n+' - t.lexer.lineno += len(t.value) - -reserved = { - 'global' : 'GLOBAL', - 'machine' : 'MACHINE', - 'in_port' : 'IN_PORT', - 'out_port' : 'OUT_PORT', - 'action' : 'ACTION', - 'transition' : 'TRANS', - 'structure' : 'STRUCT', - 'external_type' : 'EXTERN_TYPE', - 'enumeration' : 'ENUM', - 'peek' : 'PEEK', - 'enqueue' : 'ENQUEUE', - 'copy_head' : 'COPY_HEAD', - 'check_allocate' : 'CHECK_ALLOCATE', - 'check_stop_slots' : 'CHECK_STOP_SLOTS', - 'if' : 'IF', - 'else' : 'ELSE', - 'return' : 'RETURN', - 'THIS' : 'THIS', - 'CHIP' : 'CHIP', - 'void' : 'VOID', - 'new' : 'NEW', -} - -literals = ':[]{}(),=' - -tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE', - 'LEFTSHIFT', 'RIGHTSHIFT', - 'NOT', 'AND', 'OR', - 'PLUS', 'DASH', 'STAR', 'SLASH', - 'DOUBLE_COLON', 'SEMICOLON', - 'ASSIGN', 'DOT', - 'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ] -tokens += reserved.values() - -t_EQ = r'==' -t_NE = r'!=' -t_LT = r'<' -t_GT = r'>' -t_LE = r'<=' -t_GE = r'>=' -t_LEFTSHIFT = r'<<' -t_RIGHTSHIFT = r'>>' -t_NOT = r'!' -t_AND = r'&&' -t_OR = r'\|\|' -t_PLUS = r'\+' -t_DASH = r'-' -t_STAR = r'\*' -t_SLASH = r'/' -t_DOUBLE_COLON = r'::' -t_SEMICOLON = r';' -t_ASSIGN = r':=' -t_DOT = r'\.' - -class TokenError(Exception): - def __init__(self, msg, t): - super(TokenError, self).__init__(msg) - self.token = t - -class ParseError(Exception): - def __init__(self, msg, t): - super(ParseError, self).__init__(msg) - self.token = t - -def t_error(t): - raise TokenError("Illegal character", t) - -def t_IDENT(t): - r'[a-zA-Z_][a-zA-Z_0-9]*' - if t.value == 'true': - t.type = 'LIT_BOOL' - t.value = True - return t - - if t.value == 'false': - t.type = 'LIT_BOOL' - t.value = False - return t - - if t.value.startswith('LATENCY_'): - t.type = 'LATENCY' - return t - - t.type = reserved.get(t.value, 'IDENT') # Check for reserved words - return t - -def t_FLOATNUMBER(t): - '[0-9]+[.][0-9]+' - try: - t.value = float(t.value) - except ValueError: - raise TokenError("Illegal float", t) - return t - -def t_NUMBER(t): - r'[0-9]+' - try: - t.value = int(t.value) - except ValueError: - raise TokenError("Illegal number", t) - return t - -def t_STRING1(t): - r'\"[^"\n]*\"' - t.type = 'STRING' - return t - -def t_STRING2(t): - r"\'[^'\n]*\'" - t.type = 'STRING' - return t - - -def p_file(p): - "file : decl_l" - p[0] = [ x for x in p[1] if x is not None ] - -def p_error(t): - raise ParseError("Syntax error", t) - -def p_empty(p): - "empty :" - pass - -def p_decl_l(p): - "decl_l : decls" - p[0] = p[1] - -def p_decls(p): - """decls : decl decls - | empty""" - if len(p) == 3: - p[0] = [ p[1] ] + p[2] - elif len(p) == 2: - p[0] = [] - -def p_decl(p): - """decl : d_machine - | d_action - | d_in_port - | d_out_port - | t_trans - | d_extern - | d_global - | d_struct - | d_enum - | d_object - | d_func_decl - | d_func_def""" - p[0] = p[1] - -def p_d_machine(p): - """d_machine : MACHINE '(' ident pair_l ')' ':' param_l '{' decl_l '}'""" - - if len(p) == 9: - decl_l = p[7] - elif len(p) == 11: - decl_l = p[9] - decls = [ x for x in decl_l if x is not None ] - p[0] = Machine(p[3], decls) - -def p_d_action(p): - "d_action : ACTION '(' ident pair_l ')' statement_l" - p[0] = Action(p[3]) - -def p_d_in_port(p): - "d_in_port : IN_PORT '(' ident ',' type ',' var pair_l ')' statement_l" - p[0] = InPort(p[3]) - -def p_d_out_port(p): - "d_out_port : OUT_PORT '(' ident ',' type ',' var pair_l ')' SEMICOLON" - p[0] = OutPort(p[3]) - -def p_t_trans(p): - """t_trans : TRANS '(' ident_l ',' ident_l ',' ident pair_l ')' ident_l - | TRANS '(' ident_l ',' ident_l pair_l ')' ident_l""" - p[0] = Transition("transition") - -def p_d_extern(p): - """d_extern : EXTERN_TYPE '(' type pair_l ')' SEMICOLON - | EXTERN_TYPE '(' type pair_l ')' '{' type_methods '}'""" - p[0] = Extern(p[3]) - -def p_d_global(p): - "d_global : GLOBAL '(' type pair_l ')' '{' type_members '}'" - p[0] = Global(p[3]) - -def p_d_struct(p): - "d_struct : STRUCT '(' type pair_l ')' '{' type_members '}'" - p[0] = Struct(p[3]) - -def p_d_enum(p): - "d_enum : ENUM '(' type pair_l ')' '{' type_enums '}'" - p[0] = Enum(p[3]) - -def p_d_object(p): - "d_object : type ident pair_l SEMICOLON" - p[0] = Object(p[2]) - -def p_d_func_decl(p): - """d_func_decl : void ident '(' param_l ')' pair_l SEMICOLON - | type ident '(' param_l ')' pair_l SEMICOLON""" - pass - -def p_d_func_def(p): - """d_func_def : void ident '(' param_l ')' pair_l statement_l - | type ident '(' param_l ')' pair_l statement_l""" - p[0] = Function(p[2]) - -# Type fields -def p_type_members(p): - """type_members : type_member type_members - | empty""" - pass - -def p_type_member(p): - """type_member : type ident pair_l SEMICOLON - | type ident ASSIGN expr SEMICOLON""" - pass - -# Methods -def p_type_methods(p): - """type_methods : type_method type_methods - | empty""" - pass - -def p_type_method(p): - "type_method : type_or_void ident '(' type_l ')' pair_l SEMICOLON" - pass - -# Enum fields -def p_type_enums(p): - """type_enums : type_enum type_enums - | empty""" - pass - -def p_type_enum(p): - "type_enum : ident pair_l SEMICOLON" - pass - -# Type -def p_type_l(p): - """type_l : types - | empty""" - pass - -def p_types(p): - """types : type ',' types - | type""" - pass - -def p_type(p): - "type : ident" - p[0] = p[1] - -def p_void(p): - "void : VOID" - p[0] = None - -def p_type_or_void(p): - """type_or_void : type - | void""" - p[0] = p[1] - -# Formal Param -def p_param_l(p): - """param_l : params - | empty""" - pass - -def p_params(p): - """params : param ',' params - | param""" - pass - -def p_param(p): - "param : type ident" - pass - -# Idents and lists -def p_ident(p): - "ident : IDENT" - p[0] = p[1] - -def p_ident_l(p): - """ident_l : '{' idents '}' - | ident""" - p[0] = p[1] - -def p_idents(p): - """idents : ident SEMICOLON idents - | ident ',' idents - | ident idents - | empty""" - pass - -# Pair and pair lists -def p_pair_l(p): - """pair_l : ',' pairs - | empty""" - if len(p) == 3: - p[0] = p[2] - elif len(p) == 2: - p[0] = None - -def p_pairs(p): - """pairs : pair ',' pairs - | pair""" - if len(p) == 4: - p[3].append(p[1]) - p[0] = p[3] - elif len(p) == 2: - p[0] = [ p[1] ] - -def p_pair(p): - """pair : ident '=' STRING - | ident '=' ident - | STRING""" - if len(p) == 4: - p[0] = p[1], p[3] - elif len(p) == 2: - p[0] = "short", p[1] - -# Below are the rules for action descriptions -def p_statement_l(p): - "statement_l : '{' statements '}'" - pass - -def p_statements(p): - """statements : statement statements - | empty""" - pass - -def p_expr_l(p): - """expr_l : expr ',' expr_l - | expr - | empty""" - pass - -def p_statement(p): - """statement : expr SEMICOLON - | expr ASSIGN expr SEMICOLON - | ENQUEUE '(' var ',' type pair_l ')' statement_l - | PEEK '(' var ',' type ')' statement_l - | COPY_HEAD '(' var ',' var pair_l ')' SEMICOLON - | CHECK_ALLOCATE '(' var ')' SEMICOLON - | CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMICOLON - | if_statement - | RETURN expr SEMICOLON""" - pass - -def p_if_statement(p): - """if_statement : IF '(' expr ')' statement_l ELSE statement_l - | IF '(' expr ')' statement_l - | IF '(' expr ')' statement_l ELSE if_statement""" - pass - -def p_expr(p): - """expr : var - | literal - | enumeration - | ident '(' expr_l ')' - | NEW type - | THIS DOT var '[' expr ']' DOT var DOT ident '(' expr_l ')' - | THIS DOT var '[' expr ']' DOT var DOT ident - | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' expr_l ')' - | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident - | expr DOT ident - | expr DOT ident '(' expr_l ')' - | type DOUBLE_COLON ident '(' expr_l ')' - | expr '[' expr_l ']' - | expr STAR expr - | expr SLASH expr - | expr PLUS expr - | expr DASH expr - | expr LT expr - | expr GT expr - | expr LE expr - | expr GE expr - | expr EQ expr - | expr NE expr - | expr AND expr - | expr OR expr - | NOT expr - | expr RIGHTSHIFT expr - | expr LEFTSHIFT expr - | '(' expr ')'""" - pass - -def p_literal(p): - """literal : STRING - | NUMBER - | FLOATNUMBER - | LIT_BOOL""" - pass - -def p_enumeration(p): - "enumeration : ident ':' ident" - pass - -def p_var(p): - "var : ident" - pass - -lex.lex() -yacc.yacc(write_tables=0) - -slicc_generated_cc = set([ - 'ControllerFactory.cc', - 'MachineType.cc']) - -slicc_generated_hh = set([ - 'ControllerFactory.hh', - 'MachineType.hh', - 'Types.hh', - 'protocol_name.hh' ]) - -class Machine(object): - def __init__(self, name, decls): - self.name = name - self.decls = decls - - def add(self, hh, cc): - hh.add('%s_Controller.hh' % self.name) - hh.add('%s_Profiler.hh' % self.name) - - cc.add('%s_Controller.cc' % self.name) - cc.add('%s_Profiler.cc' % self.name) - cc.add('%s_Transitions.cc' % self.name) - cc.add('%s_Wakeup.cc' % self.name) - - for decl in self.decls: - decl.add(hh, cc, self.name) - -class Declaration(object): - hh = False - cc = False - def __init__(self, name): - self.name = name - - def add(self, hh, cc, name=None): - #print '>>>', type(self).__name__, self.name - if name: - name += '_' - else: - name = "" - if self.hh: - hh.add('%s%s.hh' % (name, self.name)) - if self.cc: - cc.add('%s%s.cc' % (name, self.name)) - -class Action(Declaration): pass -class InPort(Declaration): pass -class OutPort(Declaration): pass -class Transition(Declaration): pass -class Extern(Declaration): pass -class Global(Declaration): - hh = True - cc = True -class Struct(Declaration): - hh = True - cc = True -class Enum(Declaration): - hh = True - cc = True -class Object(Declaration): pass -class Function(Declaration): - cc = True - -def read_slicc(sources): - if not isinstance(sources, (list,tuple)): - sources = [ sources ] - - sm_files = [] - for source in sources: - for sm_file in file(source, "r"): - sm_file = sm_file.strip() - if not sm_file: - continue - if sm_file.startswith("#"): - continue - sm_files.append(sm_file) - - return sm_files - -def scan(filenames): - hh = slicc_generated_hh.copy() - cc = slicc_generated_cc.copy() - - for filename in filenames: - lex.lexer.lineno = 1 - try: - print "parsing ",filename - results = yacc.parse(file(filename, 'r').read()) - except (TokenError, ParseError), e: - sys.exit("%s: %s:%d" % (e, filename, e.token.lineno)) - - for result in results: - result.add(hh, cc) - - return list(hh), list(cc) - -if __name__ == '__main__': - import sys - - hh, cc = scan(read_slicc(sys.argv[1:])) - hh.sort() - cc.sort() - print 'Headers:' - for i in hh: - print ' %s' % i - - print 'Sources:' - for i in cc: - print ' %s' % i diff --git a/src/mem/slicc/parser/parser.yy b/src/mem/slicc/parser/parser.yy deleted file mode 100644 index c8cef3b210..0000000000 --- a/src/mem/slicc/parser/parser.yy +++ /dev/null @@ -1,360 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -%{ -#include -#include -#include -#include "mem/slicc/ast/ASTs.hh" -#include - -#define YYMAXDEPTH 100000 -#define YYERROR_VERBOSE - -extern char* yytext; - -extern "C" void yyerror(char*); -extern "C" int yylex(); - -%} - -%union { - string* str_ptr; - Vector* string_vector_ptr; - std::vector* stdstring_vector_ptr; - - // Decls - DeclAST* decl_ptr; - DeclListAST* decl_list_ptr; - Vector* decl_vector_ptr; - - // TypeField - TypeFieldAST* type_field_ptr; - Vector* type_field_vector_ptr; - - // Type - TypeAST* type_ptr; - Vector* type_vector_ptr; - - // Formal Params - FormalParamAST* formal_param_ptr; - Vector* formal_param_vector_ptr; - - // Statements - StatementAST* statement_ptr; - StatementListAST* statement_list_ptr; - Vector* statement_vector_ptr; - - // Pairs - PairAST* pair_ptr; - PairListAST* pair_list_ptr; - - // Expressions - VarExprAST* var_expr_ptr; - ExprAST* expr_ptr; - Vector* expr_vector_ptr; -} - -%type type void type_or_void -%type types type_list - - // Formal Params -%type formal_param -%type formal_params formal_param_list - -%type ident field -%type ident_list idents - -%type statement if_statement -%type statement_list -%type statements - -%type decl -%type decl_list -%type decls - -%type type_members type_enums type_methods -%type type_member type_enum type_method - -%type var -%type expr literal enumeration -%type expr_list - -%type pair -%type pair_list pairs - -%token IDENT STRING NUMBER FLOATNUMBER LIT_BOOL VOID -%token IMBED IMBED_TYPE -%token CHIP THIS -%token ASSIGN DOUBLE_COLON DOT SEMICOLON COLON -%token GLOBAL_DECL MACHINE_DECL IN_PORT_DECL OUT_PORT_DECL -%token PEEK ENQUEUE COPY_HEAD CHECK_ALLOCATE CHECK_STOP_SLOTS -//%token DEQUEUE REMOVE_EARLY SKIP_EARLY PEEK_EARLY -%token DEBUG_EXPR_TOKEN DEBUG_MSG_TOKEN -%token ACTION_DECL TRANSITION_DECL TYPE_DECL STRUCT_DECL EXTERN_TYPE_DECL ENUM_DECL -%token TYPE_FIELD OTHER IF ELSE RETURN NEW - -%token EQ NE '<' '>' LE GE NOT AND OR PLUS DASH STAR SLASH RIGHTSHIFT LEFTSHIFT - -%left OR -%left AND -%nonassoc EQ NE -%nonassoc '<' '>' GE LE -%left PLUS DASH -%left STAR SLASH -%nonassoc NOT -%nonassoc DOUBLE_COLON DOT '[' - -%% - -file: decl_list { g_decl_list_ptr = $1; } - -decl_list: decls { $$ = new DeclListAST($1); } - -decls: decl decls { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector; } - ; - -decl: MACHINE_DECL '(' ident pair_list ')' ':' formal_param_list '{' decl_list '}' { $$ = new MachineAST($3, $4, $7, $9); } - | ACTION_DECL '(' ident pair_list ')' statement_list { $$ = new ActionDeclAST($3, $4, $6); } - | IN_PORT_DECL '(' ident ',' type ',' var pair_list ')' statement_list { $$ = new InPortDeclAST($3, $5, $7, $8, $10); } - | OUT_PORT_DECL '(' ident ',' type ',' var pair_list ')' SEMICOLON { $$ = new OutPortDeclAST($3, $5, $7, $8); } - | TRANSITION_DECL '(' ident_list ',' ident_list ',' ident pair_list ')' ident_list { $$ = new TransitionDeclAST($3, $5, $7, $8, $10); } - | TRANSITION_DECL '(' ident_list ',' ident_list pair_list ')' ident_list { $$ = new TransitionDeclAST($3, $5, NULL, $6, $8); } - | EXTERN_TYPE_DECL '(' type pair_list ')' SEMICOLON { $4->addPair(new PairAST("external", "yes")); $$ = new TypeDeclAST($3, $4, NULL); } - | EXTERN_TYPE_DECL '(' type pair_list ')' '{' type_methods '}' { $4->addPair(new PairAST("external", "yes")); $$ = new TypeDeclAST($3, $4, $7); } - | GLOBAL_DECL '(' type pair_list ')' '{' type_members '}' { $4->addPair(new PairAST("global", "yes"));$$ = new TypeDeclAST($3, $4, $7); } - | STRUCT_DECL '(' type pair_list ')' '{' type_members '}' { $$ = new TypeDeclAST($3, $4, $7); } - | ENUM_DECL '(' type pair_list ')' '{' type_enums '}' { $4->addPair(new PairAST("enumeration", "yes")); $$ = new EnumDeclAST($3, $4, $7); } - | type ident pair_list SEMICOLON { $$ = new ObjDeclAST($1, $2, $3); } - | type ident '(' formal_param_list ')' pair_list SEMICOLON { $$ = new FuncDeclAST($1, $2, $4, $6, NULL); } // non-void function - | void ident '(' formal_param_list ')' pair_list SEMICOLON { $$ = new FuncDeclAST($1, $2, $4, $6, NULL); } // void function - | type ident '(' formal_param_list ')' pair_list statement_list { $$ = new FuncDeclAST($1, $2, $4, $6, $7); } // non-void function - | void ident '(' formal_param_list ')' pair_list statement_list { $$ = new FuncDeclAST($1, $2, $4, $6, $7); } // void function - ; - -// Type fields - -type_members: type_member type_members { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector; } - ; - -type_member: type ident pair_list SEMICOLON { $$ = new TypeFieldMemberAST($1, $2, $3, NULL); } - | type ident ASSIGN expr SEMICOLON { $$ = new TypeFieldMemberAST($1, $2, new PairListAST(), $4); } - ; - -// Methods -type_methods: type_method type_methods { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector; } - ; - -type_method: type_or_void ident '(' type_list ')' pair_list SEMICOLON { $$ = new TypeFieldMethodAST($1, $2, $4, $6); } - ; - -// Enum fields -type_enums: type_enum type_enums { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector; } - ; - -type_enum: ident pair_list SEMICOLON { $$ = new TypeFieldEnumAST($1, $2); } - ; - -// Type -type_list : types { $$ = $1; } - | { $$ = new Vector; } - ; - -types : type ',' types { $3->insertAtTop($1); $$ = $3; } - | type { $$ = new Vector; $$->insertAtTop($1); } - ; - -type: ident { $$ = new TypeAST($1); } - ; - -void: VOID { $$ = new TypeAST($1); } - ; - -type_or_void: type { $$ = $1; } - | void { $$ = $1; } - ; - -// Formal Param -formal_param_list : formal_params { $$ = $1; } - | { $$ = new Vector; } - ; - -formal_params : formal_param ',' formal_params { $3->insertAtTop($1); $$ = $3; } - | formal_param { $$ = new Vector; $$->insertAtTop($1); } - ; - -formal_param : type ident { $$ = new FormalParamAST($1, $2); } - ; - -// Idents and lists -ident: IDENT { $$ = $1; }; - -ident_list: '{' idents '}' { $$ = $2; } - | ident { $$ = new Vector; $$->insertAtTop(*($1)); delete $1; } - ; - -idents: ident SEMICOLON idents { $3->insertAtTop(*($1)); $$ = $3; delete $1; } - | ident ',' idents { $3->insertAtTop(*($1)); $$ = $3; delete $1; } - | ident idents { $2->insertAtTop(*($1)); $$ = $2; delete $1; } - | { $$ = new Vector; } - ; - -// Pair and pair lists -pair_list: ',' pairs { $$ = $2; } - | { $$ = new PairListAST(); } - -pairs : pair ',' pairs { $3->addPair($1); $$ = $3; } - | pair { $$ = new PairListAST(); $$->addPair($1); } - ; - -pair : ident '=' STRING { $$ = new PairAST($1, $3); } - | ident '=' ident { $$ = new PairAST($1, $3); } - | STRING { $$ = new PairAST(new string("short"), $1); } - ; - -// Below are the rules for action descriptions - -statement_list: '{' statements '}' { $$ = new StatementListAST($2); } - ; - -statements: statement statements { $2->insertAtTop($1); $$ = $2; } - | { $$ = new Vector; } - ; - -expr_list: expr ',' expr_list { $3->insertAtTop($1); $$ = $3; } - | expr { $$ = new Vector; $$->insertAtTop($1); } - | { $$ = new Vector; } - ; - -statement: expr SEMICOLON { $$ = new ExprStatementAST($1); } - | expr ASSIGN expr SEMICOLON { $$ = new AssignStatementAST($1, $3); } - | ENQUEUE '(' var ',' type pair_list ')' statement_list { $$ = new EnqueueStatementAST($3, $5, $6, $8); } - | PEEK '(' var ',' type ')' statement_list { $$ = new PeekStatementAST($3, $5, $7, "peek"); } -// | PEEK_EARLY '(' var ',' type ')' statement_list { $$ = new PeekStatementAST($3, $5, $7, "peekEarly"); } - | COPY_HEAD '(' var ',' var pair_list ')' SEMICOLON { $$ = new CopyHeadStatementAST($3, $5, $6); } - | CHECK_ALLOCATE '(' var ')' SEMICOLON { $$ = new CheckAllocateStatementAST($3); } - | CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMICOLON { $$ = new CheckStopSlotsStatementAST($3, $5, $7); } - | if_statement { $$ = $1; } - | RETURN expr SEMICOLON { $$ = new ReturnStatementAST($2); } - ; - -if_statement: IF '(' expr ')' statement_list ELSE statement_list { $$ = new IfStatementAST($3, $5, $7); } - | IF '(' expr ')' statement_list { $$ = new IfStatementAST($3, $5, NULL); } - | IF '(' expr ')' statement_list ELSE if_statement { $$ = new IfStatementAST($3, $5, new StatementListAST($7)); } - ; - -expr: var { $$ = $1; } - | literal { $$ = $1; } - | enumeration { $$ = $1; } - | ident '(' expr_list ')' { $$ = new FuncCallExprAST($1, $3); } - | NEW type { $$ = new NewExprAST($2); } - -// globally access a local chip component and call a method - | THIS DOT var '[' expr ']' DOT var DOT ident '(' expr_list ')' { $$ = new ChipComponentAccessAST($3, $5, $8, $10, $12 ); } -// globally access a local chip component and access a data member - | THIS DOT var '[' expr ']' DOT var DOT field { $$ = new ChipComponentAccessAST($3, $5, $8, $10 ); } -// globally access a specified chip component and call a method - | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' expr_list ')' { $$ = new ChipComponentAccessAST($3, $6, $8, $11, $13, $15 ); } -// globally access a specified chip component and access a data member - | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field { $$ = new ChipComponentAccessAST($3, $6, $8, $11, $13 ); } - - - | expr DOT field { $$ = new MemberExprAST($1, $3); } - | expr DOT ident '(' expr_list ')' { $$ = new MethodCallExprAST($1, $3, $5); } - | type DOUBLE_COLON ident '(' expr_list ')' { $$ = new MethodCallExprAST($1, $3, $5); } - | expr '[' expr_list ']' { $$ = new MethodCallExprAST($1, new string("lookup"), $3); } - | expr STAR expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr SLASH expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr PLUS expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr DASH expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr '<' expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr '>' expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr LE expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr GE expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr EQ expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr NE expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr AND expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr OR expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr RIGHTSHIFT expr { $$ = new InfixOperatorExprAST($1, $2, $3); } - | expr LEFTSHIFT expr { $$ = new InfixOperatorExprAST($1, $2, $3); } -// | NOT expr { $$ = NULL; } // FIXME - unary not -// | DASH expr %prec NOT { $$ = NULL; } // FIXME - unary minus - | '(' expr ')' { $$ = $2; } - ; - -literal: STRING { $$ = new LiteralExprAST($1, "string"); } - | NUMBER { $$ = new LiteralExprAST($1, "int"); } - | FLOATNUMBER { $$ = new LiteralExprAST($1, "int"); } - | LIT_BOOL { $$ = new LiteralExprAST($1, "bool"); } - ; - -enumeration: ident ':' ident { $$ = new EnumExprAST(new TypeAST($1), $3); } - ; - -var: ident { $$ = new VarExprAST($1); } - ; - -field: ident { $$ = $1; } - ; - -%% - -extern FILE *yyin; - -DeclListAST* parse(string filename) -{ - FILE *file; - file = fopen(filename.c_str(), "r"); - if (!file) { - cerr << "Error: Could not open file: " << filename << endl; - exit(1); - } - g_line_number = 1; - g_file_name() = filename; - yyin = file; - g_decl_list_ptr = NULL; - yyparse(); - return g_decl_list_ptr; -} - -extern "C" void yyerror(char* s) -{ - fprintf(stderr, "%s:%d: %s at %s\n", g_file_name().c_str(), g_line_number, s, yytext); - exit(1); -} - diff --git a/src/mem/slicc/slicc_global.hh b/src/mem/slicc/slicc_global.hh deleted file mode 100644 index 40a00c9d20..0000000000 --- a/src/mem/slicc/slicc_global.hh +++ /dev/null @@ -1,125 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SLICC_GLOBAL_H -#define SLICC_GLOBAL_H - -#include - -#include "mem/gems_common/std-includes.hh" -#include "mem/gems_common/Map.hh" - -typedef unsigned char uint8; -typedef unsigned int uint32; -typedef unsigned long long uint64; - -typedef signed char int8; -typedef int int32; -typedef long long int64; - -typedef long long integer_t; -typedef unsigned long long uinteger_t; - -const bool ASSERT_FLAG = true; - -// when CHECK_RESOURCE_DEADLOCK is enabled, slicc will generate additional code -// that works in conjuction with the resources rank value specified in the protocol -// to detect invalid resource stalls as soon as they occur. -const bool CHECK_INVALID_RESOURCE_STALLS = false; - -#undef assert -#define assert(EXPR) ASSERT(EXPR) - -#define ASSERT(EXPR)\ -{\ - if (ASSERT_FLAG) {\ - if (!(EXPR)) {\ - cerr << "failed assertion '"\ - << #EXPR << "' at fn "\ - << __PRETTY_FUNCTION__ << " in "\ - << __FILE__ << ":"\ - << __LINE__ << endl;\ - if(isatty(STDERR_FILENO)) {\ - cerr << "At this point you might want to attach a debug to ";\ - cerr << "the running and get to the" << endl;\ - cerr << "crash site; otherwise press enter to continue" << endl;\ - cerr << "PID: " << getpid();\ - cerr << endl << flush; \ - char c; \ - cin.get(c); \ - }\ - abort();\ - }\ - }\ -} - -class State; -class Event; -class Symbol; -class Var; - -namespace __gnu_cxx { - template <> struct hash - { - size_t operator()(State* s) const { return (size_t) s; } - }; - template <> struct hash - { - size_t operator()(Event* s) const { return (size_t) s; } - }; - template <> struct hash - { - size_t operator()(Symbol* s) const { return (size_t) s; } - }; - template <> struct hash - { - size_t operator()(Var* s) const { return (size_t) s; } - }; -} // namespace __gnu_cxx - -namespace std { - template <> struct equal_to - { - bool operator()(Event* s1, Event* s2) const { return s1 == s2; } - }; - template <> struct equal_to - { - bool operator()(State* s1, State* s2) const { return s1 == s2; } - }; - template <> struct equal_to - { - bool operator()(Symbol* s1, Symbol* s2) const { return s1 == s2; } - }; - template <> struct equal_to - { - bool operator()(Var* s1, Var* s2) const { return s1 == s2; } - }; -} // namespace std - -#endif //SLICC_GLOBAL_H diff --git a/src/mem/slicc/symbols/Action.hh b/src/mem/slicc/symbols/Action.hh deleted file mode 100644 index dbb0c836a2..0000000000 --- a/src/mem/slicc/symbols/Action.hh +++ /dev/null @@ -1,52 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -#ifndef ACTION_H -#define ACTION_H - -#include "mem/slicc/symbols/Symbol.hh" - -class Action : public Symbol { -public: - Action(string id, - const Map& resources, - const Location& location, - const Map& pairs) : Symbol(id, location, pairs) { m_resources = resources; } - const Map& getResources() const { return m_resources; } - void print(ostream& out) const { out << "[Action: " << getIdent() << "]"; } - -private: - Map m_resources; -}; - -#endif //ACTION_H diff --git a/src/mem/slicc/symbols/Action.py b/src/mem/slicc/symbols/Action.py new file mode 100644 index 0000000000..880fab15ac --- /dev/null +++ b/src/mem/slicc/symbols/Action.py @@ -0,0 +1,38 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class Action(Symbol): + def __init__(self, table, ident, resources, location, pairs): + super(Action, self).__init__(table, ident, location, pairs) + self.resources = resources + + def __repr__(self): + return "[Action: %s]" % self.ident + +__all__ = [ "Action" ] diff --git a/src/mem/slicc/symbols/Event.hh b/src/mem/slicc/symbols/Event.hh deleted file mode 100644 index 40cefc9826..0000000000 --- a/src/mem/slicc/symbols/Event.hh +++ /dev/null @@ -1,45 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -#ifndef EVENT_H -#define EVENT_H - -#include "mem/slicc/symbols/Symbol.hh" - -class Event : public Symbol { -public: - Event(string id, const Location& location, const Map& pairs) : Symbol(id, location, pairs) {} - void print(ostream& out) const { out << "[Event: " << getIdent() << "]"; } -}; - -#endif //EVENT_H diff --git a/src/mem/slicc/symbols/Event.py b/src/mem/slicc/symbols/Event.py new file mode 100644 index 0000000000..9ff4d8ba75 --- /dev/null +++ b/src/mem/slicc/symbols/Event.py @@ -0,0 +1,34 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class Event(Symbol): + def __repr__(self): + return "[Event: %s]" % self.ident + +__all__ = [ "Event" ] diff --git a/src/mem/slicc/symbols/Func.cc b/src/mem/slicc/symbols/Func.cc deleted file mode 100644 index d29138b389..0000000000 --- a/src/mem/slicc/symbols/Func.cc +++ /dev/null @@ -1,143 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Func.cc - * - * Description: See Func.hh - * - * $Id$ - * - */ - -#include "mem/slicc/symbols/Func.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -Func::Func(string id, const Location& location, - Type* type_ptr, const Vector& param_type_vec, - const Vector& param_string_vec, string body, - const Map& pairs, StateMachine* machine_ptr) - : Symbol(id, location, pairs) -{ - m_type_ptr = type_ptr; - m_param_type_vec = param_type_vec; - m_param_string_vec = param_string_vec; - m_body = body; - m_isInternalMachineFunc = false; - - if (machine_ptr == NULL) { - m_c_ident = id; - } else if (existPair("external") || existPair("primitive")) { - m_c_ident = id; - } else { - m_machineStr = machine_ptr->toString(); - m_c_ident = m_machineStr + "_" + id; // Append with machine name - m_isInternalMachineFunc = true; - } -} - -void Func::funcPrototype(string& code) const -{ - if (isExternal()) { - // Do nothing - } else { - string return_type = m_type_ptr->cIdent(); - Type* void_type_ptr = g_sym_table.getType("void"); - if (existPair("return_by_ref") && (m_type_ptr != void_type_ptr)) { - return_type += "&"; - } - code += return_type + " " + cIdent() + "("; - int size = m_param_string_vec.size(); - for(int i=0; icIdent(); - code += return_type; - if (existPair("return_by_ref") && m_type_ptr != void_type_ptr) { - code += "&"; - } - if (!m_isInternalMachineFunc) { - code += " Chip::" + cIdent() + "("; - } else { - code += " " + m_machineStr + "_Controller::" + cIdent() + "("; - } - int size = m_param_type_vec.size(); - for(int i=0; i& param_type_vec, const Vector& param_string_vec, - string body, const Map& pairs, StateMachine* machine_ptr); - - // Destructor - ~Func() {} - - // Public Methods - string cIdent() const { return m_c_ident; } - const Vector& getParamTypes() const { return m_param_type_vec; } - Type* getReturnType() const { return m_type_ptr; } - void writeCFiles(string path) ; - void funcPrototype(string& code) const; - bool isExternal() const { return existPair("external"); } - bool isInternalMachineFunc() const { return m_isInternalMachineFunc; } - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - Func(const Func& obj); - Func& operator=(const Func& obj); - - // Data Members (m_ prefix) - Type* m_type_ptr; - Vector m_param_type_vec; - Vector m_param_string_vec; - string m_body; - string m_c_ident; - string m_machineStr; - bool m_isInternalMachineFunc; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Func& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Func& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //FUNC_H diff --git a/src/mem/slicc/symbols/Func.py b/src/mem/slicc/symbols/Func.py new file mode 100644 index 0000000000..5c812a96f4 --- /dev/null +++ b/src/mem/slicc/symbols/Func.py @@ -0,0 +1,107 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.symbols.Symbol import Symbol +from slicc.symbols.Type import Type + +class Func(Symbol): + def __init__(self, table, ident, location, return_type, param_types, + param_strings, body, pairs, machine): + super(Func, self).__init__(table, ident, location, pairs) + self.return_type = return_type + self.param_types = param_types + self.param_strings = param_strings + self.body = body + self.isInternalMachineFunc = False + + if machine is None: + self.c_ident = ident + elif "external" in self or "primitive" in self: + self.c_ident = ident + else: + self.machineStr = str(machine) + # Append with machine name + self.c_ident = "%s_%s" % (self.machineStr, ident) + self.isInternalMachineFunc = True + + def __repr__(self): + return "" + + @property + def prototype(self): + if "external" in self: + return "" + + return_type = self.return_type.c_ident + void_type = self.symtab.find("void", Type) + if "return_by_ref" in self and self.return_type != void_type: + return_type += "&" + + return "%s %s(%s);" % (return_type, self.c_ident, + ", ".join(self.param_strings)) + + def writeCodeFiles(self, path): + '''This write a function of object Chip''' + if "external" in self: + return + + code = code_formatter() + + # Header + code(''' +/** Auto generated C++ code started by $__file__:$__line__ */ + +#include "mem/protocol/Types.hh" +''') + + if self.isInternalMachineFunc: + code('#include "mem/protocol/${{self.machineStr}}_Controller.hh"') + + # Generate function header + void_type = self.symtab.find("void", Type) + return_type = self.return_type.c_ident + if "return_by_ref" in self and self.return_type != void_type: + return_type += "&" + + if self.isInternalMachineFunc: + klass = "%s_Controller" % self.machineStr + else: + klass = "Chip" + + params = ', '.join(self.param_strings) + + code(''' +$return_type ${klass}::${{self.c_ident}}($params) +{ +${{self.body}} +} +''') + code.write(path, "%s.cc" % self.c_ident) + +__all__ = [ "Func" ] diff --git a/src/mem/slicc/symbols/State.hh b/src/mem/slicc/symbols/State.hh deleted file mode 100644 index 39900d5064..0000000000 --- a/src/mem/slicc/symbols/State.hh +++ /dev/null @@ -1,45 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -#ifndef STATE_H -#define STATE_H - -#include "mem/slicc/symbols/Symbol.hh" - -class State : public Symbol { -public: - State(string id, const Location& location, const Map& pairs) : Symbol(id, location, pairs) {} - void print(ostream& out) const { out << "[State: " << getIdent() << "]"; } -}; - -#endif //STATE_H diff --git a/src/mem/slicc/symbols/State.py b/src/mem/slicc/symbols/State.py new file mode 100644 index 0000000000..1236932564 --- /dev/null +++ b/src/mem/slicc/symbols/State.py @@ -0,0 +1,34 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class State(Symbol): + def __repr__(self): + return "[State: %s]" % self.ident + +__all__ = [ "State" ] diff --git a/src/mem/slicc/symbols/StateMachine.cc b/src/mem/slicc/symbols/StateMachine.cc deleted file mode 100644 index 86f92b692d..0000000000 --- a/src/mem/slicc/symbols/StateMachine.cc +++ /dev/null @@ -1,1534 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#include "mem/slicc/symbols/StateMachine.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/generator/html_gen.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/slicc/symbols/Event.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Transition.hh" -#include "mem/slicc/symbols/Var.hh" -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/gems_common/util.hh" -#include "mem/gems_common/Vector.hh" -#include "mem/slicc/ast/FormalParamAST.hh" - -#include - -StateMachine::StateMachine(string ident, const Location& location, const Map& pairs, Vector* config_parameters) - : Symbol(ident, location, pairs) -{ - m_table_built = false; - m_config_parameters = config_parameters; - - for (int i=0; i< m_config_parameters->size(); i++) { - Var* var = new Var(m_config_parameters->ref(i)->getName(), - location, - m_config_parameters->ref(i)->getType(), - "m_"+m_config_parameters->ref(i)->getName(), - Map(), - this); - g_sym_table.registerSym(m_config_parameters->ref(i)->getName(), var); - } -} - -StateMachine::~StateMachine() -{ - // FIXME - // assert(0); -} - -void StateMachine::addState(State* state_ptr) -{ - assert(m_table_built == false); - m_state_map.add(state_ptr, m_states.size()); - m_states.insertAtBottom(state_ptr); -} - -void StateMachine::addEvent(Event* event_ptr) -{ - assert(m_table_built == false); - m_event_map.add(event_ptr, m_events.size()); - m_events.insertAtBottom(event_ptr); -} - -void StateMachine::addAction(Action* action_ptr) -{ - assert(m_table_built == false); - - // Check for duplicate action - int size = m_actions.size(); - for(int i=0; igetIdent() == action_ptr->getIdent()) { - m_actions[i]->warning("Duplicate action definition: " + m_actions[i]->getIdent()); - action_ptr->error("Duplicate action definition: " + action_ptr->getIdent()); - } - if (m_actions[i]->getShorthand() == action_ptr->getShorthand()) { - m_actions[i]->warning("Duplicate action shorthand: " + m_actions[i]->getIdent()); - m_actions[i]->warning(" shorthand = " + m_actions[i]->getShorthand()); - action_ptr->warning("Duplicate action shorthand: " + action_ptr->getIdent()); - action_ptr->error(" shorthand = " + action_ptr->getShorthand()); - } - } - - m_actions.insertAtBottom(action_ptr); -} - -void StateMachine::addTransition(Transition* trans_ptr) -{ - assert(m_table_built == false); - trans_ptr->checkIdents(m_states, m_events, m_actions); - m_transitions.insertAtBottom(trans_ptr); -} - -void StateMachine::addFunc(Func* func_ptr) -{ - // register func in the symbol table - g_sym_table.registerSym(func_ptr->toString(), func_ptr); - m_internal_func_vec.insertAtBottom(func_ptr); -} - -void StateMachine::buildTable() -{ - assert(m_table_built == false); - int numStates = m_states.size(); - int numEvents = m_events.size(); - int numTransitions = m_transitions.size(); - int stateIndex, eventIndex; - - for(stateIndex=0; stateIndex < numStates; stateIndex++) { - m_table.insertAtBottom(Vector()); - for(eventIndex=0; eventIndex < numEvents; eventIndex++) { - m_table[stateIndex].insertAtBottom(NULL); - } - } - - for(int i=0; i actions = trans_ptr->getActions(); - for(int actionIndex=0; actionIndex < actions.size(); actionIndex++) { - actions[actionIndex]->markUsed(); - } - - stateIndex = getStateIndex(trans_ptr->getStatePtr()); - eventIndex = getEventIndex(trans_ptr->getEventPtr()); - if (m_table[stateIndex][eventIndex] != NULL) { - m_table[stateIndex][eventIndex]->warning("Duplicate transition: " + m_table[stateIndex][eventIndex]->toString()); - trans_ptr->error("Duplicate transition: " + trans_ptr->toString()); - } - m_table[stateIndex][eventIndex] = trans_ptr; - } - - // Look at all actions to make sure we used them all - for(int actionIndex=0; actionIndex < m_actions.size(); actionIndex++) { - Action* action_ptr = m_actions[actionIndex]; - if (!action_ptr->wasUsed()) { - string error_msg = "Unused action: " + action_ptr->getIdent(); - if (action_ptr->existPair("desc")) { - error_msg += ", " + action_ptr->getDescription(); - } - action_ptr->warning(error_msg); - } - } - - m_table_built = true; -} - -const Transition* StateMachine::getTransPtr(int stateIndex, int eventIndex) const -{ - return m_table[stateIndex][eventIndex]; -} - -// *********************** // -// ******* C Files ******* // -// *********************** // - -void StateMachine::writeCFiles(string path) -{ - string comp = getIdent(); - string filename; - - // Output the method declarations for the class declaration - { - ostringstream sstr; - printControllerH(sstr, comp); - conditionally_write_file(path + comp + "_Controller.hh", sstr); - } - - // Output switch statement for transition table - { - ostringstream sstr; - printCSwitch(sstr, comp); - conditionally_write_file(path + comp + "_Transitions.cc", sstr); - } - - // Output the actions for performing the actions - { - ostringstream sstr; - printControllerC(sstr, comp); - conditionally_write_file(path + comp + "_Controller.cc", sstr); - } - - // Output the wakeup loop for the events - { - ostringstream sstr; - printCWakeup(sstr, comp); - conditionally_write_file(path + comp + "_Wakeup.cc", sstr); - } - - // Profiling - { - ostringstream sstr; - printProfilerC(sstr, comp); - conditionally_write_file(path + comp + "_Profiler.cc", sstr); - } - { - ostringstream sstr; - printProfilerH(sstr, comp); - conditionally_write_file(path + comp + "_Profiler.hh", sstr); - } - - // Write internal func files - for(int i=0; iwriteCFiles(path); - } - -} - -void StateMachine::printControllerH(ostream& out, string component) -{ - - m_message_buffer_names.clear(); - - out << "/** \\file " << getIdent() << ".hh" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " * Created by slicc definition of Module \"" << getShorthand() << "\"" << endl; - out << " */" << endl; - out << endl; - out << "#ifndef " << component << "_CONTROLLER_H" << endl; - out << "#define " << component << "_CONTROLLER_H" << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/ruby/common/Consumer.hh\"" << endl; - out << "#include \"mem/ruby/slicc_interface/AbstractController.hh\"" << endl; - out << "#include \"mem/protocol/TransitionResult.hh\"" << endl; - out << "#include \"mem/protocol/Types.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Profiler.hh\"" << endl; - - // include object classes - std::set seen_types; - for(int i=0; igetType()->cIdent()) == 0) { - out << "#include \"mem/protocol/" << var->getType()->cIdent() << ".hh\"" << endl; - // out << "class " << var->getType()->cIdent() << ";" << endl; - seen_types.insert(var->getType()->cIdent()); - } - } - - out << endl; - - // for adding information to the protocol debug trace - out << "extern stringstream " << component << "_" << "transitionComment;" << endl; - - out << "class " << component << "_Controller : public AbstractController {" << endl; - - /* the coherence checker needs to call isBlockExclusive() and isBlockShared() - making the Chip a friend class is an easy way to do this for now */ - out << "#ifdef CHECK_COHERENCE" << endl; - out << "#endif /* CHECK_COHERENCE */" << endl; - - out << "public:" << endl; - // out << " " << component << "_Controller(int version, Network* net_ptr);" << endl; - out << " " << component << "_Controller(const string & name);" << endl; - out << " static int getNumControllers();" << endl; - out << " void init(Network* net_ptr, const vector & argv);" << endl; - out << " MessageBuffer* getMandatoryQueue() const;" << endl; - out << " const int & getVersion() const;" << endl; - out << " const string toString() const;" << endl; - out << " const string getName() const;" << endl; - out << " const MachineType getMachineType() const;" << endl; - out << " void print(ostream& out) const;" << endl; - out << " void printConfig(ostream& out) const;" << endl; - out << " void wakeup();" << endl; - out << " void set_atomic(Address addr);" << endl; - out << " void started_writes();" << endl; - out << " void clear_atomic();" << endl; - out << " void printStats(ostream& out) const { s_profiler.dumpStats(out); }" << endl; - out << " void clearStats() { s_profiler.clearStats(); }" << endl; - out << "private:" << endl; -//added by SS -// found_to_mem = 0; - for(int i=0;isize();i++){ - out << " int m_" << m_config_parameters->ref(i)->getName() << ";" << endl; - } - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - out << " int servicing_atomic;" << endl; - out << " bool started_receiving_writes;" << endl; - out << " Address locked_read_request1;" << endl; - out << " Address locked_read_request2;" << endl; - out << " Address locked_read_request3;" << endl; - out << " Address locked_read_request4;" << endl; - out << " int read_counter;" << endl; - } - out << " int m_number_of_TBEs;" << endl; - - out << " TransitionResult doTransition(" << component << "_Event event, " << component - << "_State state, const Address& addr"; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", int priority"; - } - out << "); // in " << component << "_Transitions.cc" << endl; - out << " TransitionResult doTransitionWorker(" << component << "_Event event, " << component - << "_State state, " << component << "_State& next_state, const Address& addr"; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", int priority"; - } - out << "); // in " << component << "_Transitions.cc" << endl; - out << " string m_name;" << endl; - out << " int m_transitions_per_cycle;" << endl; - out << " int m_buffer_size;" << endl; - out << " int m_recycle_latency;" << endl; - out << " map< string, string > m_cfg;" << endl; - out << " NodeID m_version;" << endl; - out << " Network* m_net_ptr;" << endl; - out << " MachineID m_machineID;" << endl; - out << " " << component << "_Profiler s_profiler;" << endl; - out << " static int m_num_controllers;" << endl; - - // internal function protypes - out << " // Internal functions" << endl; - for(int i=0; ifuncPrototype(proto); - if (proto != "") { - out << " " << proto; - } - } - - out << " // Actions" << endl; - for(int i=0; i < numActions(); i++) { - const Action& action = getAction(i); - out << "/** \\brief " << action.getDescription() << "*/" << endl; - out << " void " << action.getIdent() << "(const Address& addr);" << endl; - } - - // the controller internal variables - out << " // Object" << endl; - for(int i=0; i < numObjects(); i++) { - const Var* var = m_objs[i]; - string template_hack = ""; - if (var->existPair("template_hack")) { - template_hack = var->lookupPair("template_hack"); - } - out << " " << var->getType()->cIdent() << template_hack << "* m_" - << var->cIdent() << "_ptr;" << endl; - - string str = "m_"+ var->cIdent() + "_ptr"; - if (var->getType()->cIdent() == "MessageBuffer") - m_message_buffer_names.push_back(str); - - } - - - out << "};" << endl; - out << "#endif // " << component << "_CONTROLLER_H" << endl; -} - -void StateMachine::printControllerC(ostream& out, string component) -{ - out << "/** \\file " << getIdent() << ".cc" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " * Created by slicc definition of Module \"" << getShorthand() << "\"" << endl; - out << " */" << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; - out << "#include \"mem/protocol/Types.hh\"" << endl; - out << "#include \"mem/ruby/system/System.hh\"" << endl; - - // include object classes - std::set seen_types; - for(int i=0; igetType()->cIdent()) == 0) { - out << "#include \"mem/protocol/" << var->getType()->cIdent() << ".hh\"" << endl; - seen_types.insert(var->getType()->cIdent()); - } - - } - - out << endl; - - out << "int " << component << "_Controller::m_num_controllers = 0;" << endl; - - // for adding information to the protocol debug trace - out << "stringstream " << component << "_" << "transitionComment;" << endl; - out << "#define APPEND_TRANSITION_COMMENT(str) (" << component << "_" << "transitionComment << str)" << endl; - - out << "/** \\brief constructor */" << endl; - out << component << "_Controller::" << component - // << "_Controller(int version, Network* net_ptr)" << endl; - << "_Controller(const string & name)" << endl; - out << " : m_name(name)" << endl; - out << "{ " << endl; - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - out << " servicing_atomic = 0;" << endl; - out << " started_receiving_writes = false;" << endl; - out << " locked_read_request1 = Address(-1);" << endl; - out << " locked_read_request2 = Address(-1);" << endl; - out << " locked_read_request3 = Address(-1);" << endl; - out << " locked_read_request4 = Address(-1);" << endl; - out << " read_counter = 0;" << endl; - } - out << " m_num_controllers++; " << endl; - for(int i=0; i < numObjects(); i++) { - const Var* var = m_objs[i]; - if ( var->cIdent().find("mandatoryQueue") != string::npos) - out << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << "();" << endl; - } - out << "}" << endl << endl; - - out << "void " << component << "_Controller::init(Network * net_ptr, const vector & argv)" << endl; - out << "{" << endl; - out << " for (size_t i=0; i < argv.size(); i+=2) {" << endl; -// out << " printf (\"ARG: %s = %s \\n \", argv[i].c_str(), argv[i+1].c_str());"<< endl; - - out << " if (argv[i] == \"version\") " << endl; - out << " m_version = atoi(argv[i+1].c_str());" << endl; - out << " else if (argv[i] == \"transitions_per_cycle\") " << endl; - out << " m_transitions_per_cycle = atoi(argv[i+1].c_str());" << endl; - out << " else if (argv[i] == \"buffer_size\") " << endl; - out << " m_buffer_size = atoi(argv[i+1].c_str());" << endl; -//added by SS - out << " else if (argv[i] == \"recycle_latency\") " << endl; - out << " m_recycle_latency = atoi(argv[i+1].c_str());" << endl; -//added by SS --> for latency -//for loop on latency_vector to check with argv[i] and assign the value to the related m_latency ... - out << " else if (argv[i] == \"number_of_TBEs\") " << endl; - out << " m_number_of_TBEs = atoi(argv[i+1].c_str());" << endl; - - if (m_config_parameters->size()) { - for(int i= 0 ; i < m_config_parameters->size(); i++) { - out << " else if (argv[i] == \"" << m_config_parameters->ref(i)->getName() << "\")" << endl; - if (m_config_parameters->ref(i)->getTypeName() == "int") - out << " m_" << m_config_parameters->ref(i)->getName() << "=" << "atoi(argv[i+1].c_str());" << endl; - else - assert(0); // only int parameters are supported right now - // if (str == "to_mem_ctrl_latency") - // out << " m_" << (*it)->c_str() << "=" << "atoi(argv[i+1].c_str())+(random() % 5);" << endl; - } - } - out << " }" << endl; - out << " m_net_ptr = net_ptr;" << endl; - out << " m_machineID.type = MachineType_" << component << ";" << endl; - out << " m_machineID.num = m_version;" << endl; - - // make configuration array - out << " for (size_t i=0; i < argv.size(); i+=2) {" << endl; - out << " if (argv[i] != \"version\") " << endl; - out << " m_cfg[argv[i]] = argv[i+1];" << endl; - out << " }" << endl; - - out << endl; - - // initialize objects - out << " // Objects" << endl; - out << " s_profiler.setVersion(m_version);" << endl; - for(int i=0; i < numObjects(); i++) { - const Var* var = m_objs[i]; - if (!var->existPair("network")) { - // Not a network port object - if (var->getType()->existPair("primitive")) { - out << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << ";\n"; - if (var->existPair("default")) { - out << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default") << ";\n"; - } - out << " }\n"; - - } else { - // Normal Object - string template_hack = ""; - if (var->existPair("template_hack")) { - template_hack = var->lookupPair("template_hack"); - } -//added by SS - string str = ""; - int found = 0; - if (var->existPair("factory")) { - out << " m_" << var->cIdent() << "_ptr = " << var->lookupPair("factory"); - } else { - if ( var->cIdent().find("mandatoryQueue") == string::npos) { - - str = " m_" + var->cIdent() + "_ptr = new " + var->getType()->cIdent() + template_hack; - out << str; - if (str.find("TBETable")!=string::npos){ - found = 1; - } - - if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) { - str = ""; - if (var->existPair("constructor_hack")) { - string constructor_hack = var->lookupPair("constructor_hack"); - str = "(" + constructor_hack + ")"; - } else { - str = "()"; - } - if (found) - str = "(m_number_of_TBEs)"; - out << str; - } - } - } - - out << ";\n"; - out << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl; - - if (var->existPair("default")) { - out << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default") - << "; // Object default" << endl; - } else if (var->getType()->hasDefault()) { - out << " (*m_" << var->cIdent() << "_ptr) = " << var->getType()->getDefault() - << "; // Type " << var->getType()->getIdent() << " default" << endl; - } - - // Set ordering - if (var->existPair("ordered") && !var->existPair("trigger_queue")) { - // A buffer - string ordered = var->lookupPair("ordered"); - out << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n"; - } - - // Set randomization - if (var->existPair("random")) { - // A buffer - string value = var->lookupPair("random"); - out << " m_" << var->cIdent() << "_ptr->setRandomization(" << value << ");\n"; - } - - // Set Priority - if (var->getType()->isBuffer() && var->existPair("rank") && !var->existPair("trigger_queue")) { - string rank = var->lookupPair("rank"); - out << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n"; - } - } - } else { - // Network port object - string network = var->lookupPair("network"); - string ordered = var->lookupPair("ordered"); - string vnet = var->lookupPair("virtual_network"); - - assert (var->getMachine() != NULL); - out << " m_" << var->cIdent() << "_ptr = m_net_ptr->get" - << network << "NetQueue(m_version+MachineType_base_number(string_to_MachineType(\"" - << var->getMachine()->getIdent() << "\")), " - << ordered << ", " << vnet << ");\n"; - out << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl; - - // Set ordering - if (var->existPair("ordered")) { - // A buffer - string ordered = var->lookupPair("ordered"); - out << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n"; - } - - // Set randomization - if (var->existPair("random")) { - // A buffer - string value = var->lookupPair("random"); - out << " m_" << var->cIdent() << "_ptr->setRandomization(" << value << ");\n"; - } - - // Set Priority - if (var->existPair("rank")) { - string rank = var->lookupPair("rank"); - out << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n"; - } - - // Set buffer size - if (var->getType()->isBuffer()) { - out << " if (m_buffer_size > 0) {\n"; - out << " m_" << var->cIdent() << "_ptr->setSize(m_buffer_size);\n"; - out << " }\n"; - } - - // set description (may be overriden later by port def) - out << " m_" << var->cIdent() - << "_ptr->setDescription(\"[Version \" + int_to_string(m_version) + \", " - << component << ", name=" << var->cIdent() << "]\");" << endl; - out << endl; - } - } - - // Set the queue consumers - out << endl; - for(int i=0; i < m_in_ports.size(); i++) { - const Var* port = m_in_ports[i]; - out << " " << port->getCode() << ".setConsumer(this);" << endl; - } - - // Set the queue descriptions - out << endl; - for(int i=0; i < m_in_ports.size(); i++) { - const Var* port = m_in_ports[i]; - out << " " << port->getCode() - << ".setDescription(\"[Version \" + int_to_string(m_version) + \", " - << component << ", " << port->toString() << "]\");" << endl; - } - - // Initialize the transition profiling - out << endl; - for(int i=0; i& action_vec = t.getActions(); - int numActions = action_vec.size(); - - // Figure out if we stall - bool stall = false; - for (int i=0; igetIdent() == "z_stall") { - stall = true; - } - } - - // Only possible if it is not a 'z' case - if (!stall) { - out << " s_profiler.possibleTransition(" << component << "_State_" - << t.getStatePtr()->getIdent() << ", " << component << "_Event_" - << t.getEventPtr()->getIdent() << ");" << endl; - } - } - - //added by SS to initialize recycle_latency of message buffers - std::vector::const_iterator it; - for ( it=m_message_buffer_names.begin() ; it != m_message_buffer_names.end(); it++ ){ - out << " "<< (*it).c_str() << "->setRecycleLatency(m_recycle_latency);" << endl; - } - - - out << "}" << endl; - - out << endl; - - bool has_mandatory_q = false; - for(int i=0; i < m_in_ports.size(); i++) { - if (m_in_ports[i]->getCode().find("mandatoryQueue_ptr")!= string::npos) - has_mandatory_q = true; - } - - out << "int " << component << "_Controller::getNumControllers() {" << endl; - out << " return m_num_controllers;" << endl; - out << "}" << endl; - - out << endl; - - out << "MessageBuffer* " << component << "_Controller::getMandatoryQueue() const {" << endl; - if (has_mandatory_q) - out << " return m_" << component << "_mandatoryQueue_ptr;" << endl; - else - out << " return NULL;" << endl; - out << "}" << endl; - - out << endl; - - out << "const int & "<::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) {" << endl; - out << " out << \" \" << (*it).first << \": \" << (*it).second << endl;" << endl; - out << " }" << endl; - out << "}" << endl; - - out << endl; - out << "// Actions" << endl; - out << endl; - - for(int i=0; i < numActions(); i++) { - const Action& action = getAction(i); - if (action.existPair("c_code")) { - out << "/** \\brief " << action.getDescription() << "*/" << endl; - out << "void " << component << "_Controller::" - << action.getIdent() << "(const Address& addr)" << endl; - out << "{" << endl; - out << " DEBUG_MSG(GENERATED_COMP, HighPrio,\"executing\");" << endl; -//added by SS -//it should point to m_latency... -//so I should change the string output of this lookup - - - string c_code_string = action.lookupPair("c_code"); - - out << c_code_string; - - out << "}" << endl; - } - out << endl; - } -} - -void StateMachine::printCWakeup(ostream& out, string component) -{ - out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << "// " << getIdent() << ": " << getShorthand() << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; - out << "#include \"mem/protocol/Types.hh\"" << endl; - out << "#include \"mem/ruby/system/System.hh\"" << endl; - out << endl; - out << "void " << component << "_Controller::wakeup()" << endl; - out << "{" << endl; - // out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,*this);" << endl; - // out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,g_eventQueue_ptr->getTime());" << endl; - out << endl; - out << "int counter = 0;" << endl; - out << " while (true) {" << endl; - out << " // Some cases will put us into an infinite loop without this limit" << endl; - out << " assert(counter <= m_transitions_per_cycle);" << endl; - out << " if (counter == m_transitions_per_cycle) {" << endl; - out << " g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we're fully utilized" << endl; - out << " g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again" << endl; - out << " break;" << endl; - out << " }" << endl; - - // InPorts - // - // Find the position of the mandatory queue in the vector so that we can print it out first - int j = -1; - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - for(int i=0; i < m_in_ports.size(); i++) { - const Var* port = m_in_ports[i]; - assert(port->existPair("c_code_in_port")); - if (port->toString().find("mandatoryQueue_in") != string::npos) { - assert (j == -1); - j = i; - } - else { - cout << port->toString() << endl << flush; - } - } - - assert(j != -1); - - // print out the mandatory queue here - const Var* port = m_in_ports[j]; - assert(port->existPair("c_code_in_port")); - out << " // " - << component << "InPort " << port->toString() - << endl; - string output = port->lookupPair("c_code_in_port"); - string::size_type pos = output.find("TransitionResult result = doTransition((L1Cache_mandatory_request_type_to_event(((*in_msg_ptr)).m_Type)), L1Cache_getState(addr), addr);"); - assert(pos != string::npos); - string atomics_string = "\n \ - if ((((*in_msg_ptr)).m_Type) == CacheRequestType_ATOMIC) { \n \ - if (servicing_atomic == 0) { \n \ - if (locked_read_request1 == Address(-1)) { \n \ - assert(read_counter == 0); \n \ - locked_read_request1 = addr; \n \ - assert(read_counter == 0); \n \ - read_counter++; \n \ - } \n \ - else if (addr == locked_read_request1) { \n \ - ; // do nothing \n\ - } \n \ - else { \n \ - assert(0); // should never be here if servicing one request at a time \n\ - } \n \ - } \n \ - else if (!started_receiving_writes) { \n \ - if (servicing_atomic == 1) { \n \ - if (locked_read_request2 == Address(-1)) { \n \ - assert(locked_read_request1 != Address(-1)); \n \ - assert(read_counter == 1); \n \ - locked_read_request2 = addr; \n \ - assert(read_counter == 1); \n \ - read_counter++; \n \ - } \n \ - else if (addr == locked_read_request2) { \n \ - ; // do nothing \n\ - } \n \ - else { \n \ - assert(0); // should never be here if servicing one request at a time \n\ - } \n \ - } \n \ - else if (servicing_atomic == 2) { \n \ - if (locked_read_request3 == Address(-1)) { \n \ - assert(locked_read_request1 != Address(-1)); \n \ - assert(locked_read_request2 != Address(-1)); \n \ - assert(read_counter == 1); \n \ - locked_read_request3 = addr; \n \ - assert(read_counter == 2); \n \ - read_counter++; \n \ - } \n \ - else if (addr == locked_read_request3) { \n \ - ; // do nothing \n\ - } \n \ - else { \n \ - assert(0); // should never be here if servicing one request at a time \n\ - } \n \ - } \n \ - else if (servicing_atomic == 3) { \n \ - if (locked_read_request4 == Address(-1)) { \n \ - assert(locked_read_request1 != Address(-1)); \n \ - assert(locked_read_request2 != Address(-1)); \n \ - assert(locked_read_request3 != Address(-1)); \n \ - assert(read_counter == 1); \n \ - locked_read_request4 = addr; \n \ - assert(read_counter == 3); \n \ - read_counter++; \n \ - } \n \ - else if (addr == locked_read_request4) { \n \ - ; // do nothing \n\ - } \n \ - else { \n \ - assert(0); // should never be here if servicing one request at a time \n\ - } \n \ - } \n \ - else { \n \ - assert(0); \n \ - } \n \ - } \n \ - } \n \ - else { \n \ - if (servicing_atomic > 0) { \n \ - // reset \n \ - servicing_atomic = 0; \n \ - read_counter = 0; \n \ - started_receiving_writes = false; \n \ - locked_read_request1 = Address(-1); \n \ - locked_read_request2 = Address(-1); \n \ - locked_read_request3 = Address(-1); \n \ - locked_read_request4 = Address(-1); \n \ - } \n \ - } \n \ - "; - output.insert(pos, atomics_string); - /*string foo = "// Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n"; - string::size_type next_pos = output.find(foo, pos); - next_pos = next_pos + foo.length(); - - assert(next_pos != string::npos); - string complete = " }\n"; - output.insert(next_pos, complete);*/ - //out << port->lookupPair("c_code_in_port"); - out << output; - out << endl; - } - for(int i=0; i < m_in_ports.size(); i++) { - const Var* port = m_in_ports[i]; - // don't print out mandatory queue twice - if (i != j) { - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - if (port->toString().find("forwardRequestNetwork_in") != string::npos) { - out << " bool postpone = false;" << endl; - out << " if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) {" << endl; - out << " const RequestMsg* in_msg_ptr;" << endl; - out << " in_msg_ptr = dynamic_cast(((*m_L1Cache_forwardToCache_ptr)).peek());" << endl; - out << " if ((((servicing_atomic == 1) && (locked_read_request1 == ((*in_msg_ptr)).m_Address)) || " << endl; - out << " ((servicing_atomic == 2) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address)) || " << endl; - out << " ((servicing_atomic == 3) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address)) || " << endl; - out << " ((servicing_atomic == 4) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) {" << endl; -// out << " (locked_read_request2 == ((*in_msg_ptr)).m_Address) || (locked_read_request3 == ((*in_msg_ptr)).m_Address) || " << endl; -// out << " (locked_read_request4 == ((*in_msg_ptr)).m_Address))) { " << endl; - - out << " postpone = true;" << endl; - out << " }" << endl; - - out << " }" << endl; - out << " if (!postpone) {" << endl; - } - } - assert(port->existPair("c_code_in_port")); - out << " // " - << component << "InPort " << port->toString() - << endl; - out << port->lookupPair("c_code_in_port"); - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - if (port->toString().find("forwardRequestNetwork_in") != string::npos) { - out << "}" << endl; - } - } - out << endl; - } - } - - out << " break; // If we got this far, we have nothing left todo" << endl; - out << " }" << endl; - // out << " g_eventQueue_ptr->scheduleEvent(this, 1);" << endl; - // out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; - out << "}" << endl; - out << endl; - - - // tack on two more functions - if (strncmp(component.c_str(), "L1Cache", 7) == 0) { - out << "void " << component << "_Controller::set_atomic(Address addr)" << endl; - out << "{" << endl; - out << " servicing_atomic++; " << endl; - out << "}" << endl; - out << "void " << component << "_Controller::started_writes()" << endl; - out << "{" << endl; - out << " started_receiving_writes = true; " << endl; - out << "}" << endl; - out << "void " << component << "_Controller::clear_atomic()" << endl; - out << "{" << endl; - out << " assert(servicing_atomic > 0); " << endl; - out << " read_counter--; " << endl; - out << " servicing_atomic--; " << endl; - out << " if (read_counter == 0) { " << endl; - out << " servicing_atomic = 0; " << endl; - out << " started_receiving_writes = false; " << endl; - out << " locked_read_request1 = Address(-1); " << endl; - out << " locked_read_request2 = Address(-1); " << endl; - out << " locked_read_request3 = Address(-1); " << endl; - out << " locked_read_request4 = Address(-1); " << endl; - out << " } " << endl; - out << "}" << endl; - } - else { - out << "void " << component << "_Controller::started_writes()" << endl; - out << "{" << endl; - out << " assert(0); " << endl; - out << "}" << endl; - out << "void " << component << "_Controller::set_atomic(Address addr)" << endl; - out << "{" << endl; - out << " assert(0); " << endl; - out << "}" << endl; - - out << "void " << component << "_Controller::clear_atomic()" << endl; - out << "{" << endl; - out << " assert(0); " << endl; - out << "}" << endl; - } - -} - -void StateMachine::printCSwitch(ostream& out, string component) -{ - out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << "// " << getIdent() << ": " << getShorthand() << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; - out << "#include \"mem/protocol/Types.hh\"" << endl; - out << "#include \"mem/ruby/system/System.hh\"" << endl; - out << endl; - out << "#define HASH_FUN(state, event) ((int(state)*" << component - << "_Event_NUM)+int(event))" << endl; - out << endl; - out << "#define GET_TRANSITION_COMMENT() (" << component << "_" << "transitionComment.str())" << endl; - out << "#define CLEAR_TRANSITION_COMMENT() (" << component << "_" << "transitionComment.str(\"\"))" << endl; - out << endl; - out << "TransitionResult " << component << "_Controller::doTransition(" - << component << "_Event event, " - << component << "_State state, " - << "const Address& addr" << endl; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", int priority"; - } - out << ")" << endl; - - out << "{" << endl; - out << " " << component << "_State next_state = state;" << endl; - out << endl; - out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; - out << " DEBUG_MSG(GENERATED_COMP, MedPrio,*this);" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,g_eventQueue_ptr->getTime());" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,state);" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,event);" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,addr);" << endl; - out << endl; - out << " TransitionResult result = doTransitionWorker(event, state, next_state, addr"; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", priority"; - } - out << ");" << endl; - out << endl; - out << " if (result == TransitionResult_Valid) {" << endl; - out << " DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state);" << endl; - out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; - out << " s_profiler.countTransition(state, event);" << endl; - out << " if (Debug::getProtocolTrace()) {" << endl - << " g_system_ptr->getProfiler()->profileTransition(\"" << component - << "\", m_version, addr, " << endl - << " " << component << "_State_to_string(state), " << endl - << " " << component << "_Event_to_string(event), " << endl - << " " << component << "_State_to_string(next_state), GET_TRANSITION_COMMENT());" << endl - << " }" << endl; - out << " CLEAR_TRANSITION_COMMENT();" << endl; - out << " " << component << "_setState(addr, next_state);" << endl; - out << " " << endl; - out << " } else if (result == TransitionResult_ResourceStall) {" << endl; - out << " if (Debug::getProtocolTrace()) {" << endl - << " g_system_ptr->getProfiler()->profileTransition(\"" << component - << "\", m_version, addr, " << endl - << " " << component << "_State_to_string(state), " << endl - << " " << component << "_Event_to_string(event), " << endl - << " " << component << "_State_to_string(next_state), " << endl - << " \"Resource Stall\");" << endl - << " }" << endl; - out << " } else if (result == TransitionResult_ProtocolStall) {" << endl; - out << " DEBUG_MSG(GENERATED_COMP,HighPrio,\"stalling\");" << endl - << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl; - out << " if (Debug::getProtocolTrace()) {" << endl - << " g_system_ptr->getProfiler()->profileTransition(\"" << component - << "\", m_version, addr, " << endl - << " " << component << "_State_to_string(state), " << endl - << " " << component << "_Event_to_string(event), " << endl - << " " << component << "_State_to_string(next_state), " << endl - << " \"Protocol Stall\");" << endl - << " }" << endl - << " }" << endl; - out << " return result;" << endl; - out << "}" << endl; - out << endl; - out << "TransitionResult " << component << "_Controller::doTransitionWorker(" - << component << "_Event event, " - << component << "_State state, " - << component << "_State& next_state, " - << "const Address& addr" << endl; - if(CHECK_INVALID_RESOURCE_STALLS) { - out << ", int priority" << endl; - } - out << ")" << endl; - - out << "{" << endl; - out << "" << endl; - - out << " switch(HASH_FUN(state, event)) {" << endl; - - Map > code_map; // This map will allow suppress generating duplicate code - Vector code_vec; - - for(int i=0; igetIdent() - + ", " + component + "_Event_" + t.getEventPtr()->getIdent(); - - string code; - - code += " {\n"; - // Only set next_state if it changes - if (t.getStatePtr() != t.getNextStatePtr()) { - code += " next_state = " + component + "_State_" + t.getNextStatePtr()->getIdent() + ";\n"; - } - - const Vector& action_vec = t.getActions(); - int numActions = action_vec.size(); - - // Check for resources - Vector code_sorter; - const Map& res = t.getResources(); - Vector res_keys = res.keys(); - for (int i=0; igetType()->cIdent() == "DNUCAStopTable") { - temp_code += res.lookup(res_keys[i]); - } else { - temp_code += " if (!" + (res_keys[i]->getCode()) + ".areNSlotsAvailable(" + res.lookup(res_keys[i]) + ")) {\n"; - if(CHECK_INVALID_RESOURCE_STALLS) { - // assert that the resource stall is for a resource of equal or greater priority - temp_code += " assert(priority >= "+ (res_keys[i]->getCode()) + ".getPriority());\n"; - } - temp_code += " return TransitionResult_ResourceStall;\n"; - temp_code += " }\n"; - } - code_sorter.insertAtBottom(temp_code); - } - - // Emit the code sequences in a sorted order. This makes the - // output deterministic (without this the output order can vary - // since Map's keys() on a vector of pointers is not deterministic - code_sorter.sortVector(); - for (int i=0; igetIdent() == "z_stall") { - stall = true; - } - } - - if (stall) { - code += " return TransitionResult_ProtocolStall;\n"; - } else { - for (int i=0; igetIdent() + "(addr);\n"; - } - code += " return TransitionResult_Valid;\n"; - } - code += " }\n"; - - - // Look to see if this transition code is unique. - if (code_map.exist(code)) { - code_map.lookup(code).insertAtBottom(case_string); - } else { - Vector vec; - vec.insertAtBottom(case_string); - code_map.add(code, vec); - code_vec.insertAtBottom(code); - } - } - - // Walk through all of the unique code blocks and spit out the - // corresponding case statement elements - for (int i=0; igetTime());" << endl; - out << " WARN_EXPR(addr);" << endl; - out << " WARN_EXPR(event);" << endl; - out << " WARN_EXPR(state);" << endl; - out << " ERROR_MSG(\"Invalid transition\");" << endl; - out << " }" << endl; - out << " return TransitionResult_Valid;" << endl; - out << "}" << endl; -} - -void StateMachine::printProfilerH(ostream& out, string component) -{ - out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << "// " << getIdent() << ": " << getShorthand() << endl; - out << endl; - out << "#ifndef " << component << "_PROFILER_H" << endl; - out << "#define " << component << "_PROFILER_H" << endl; - out << endl; - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl; - out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl; - out << endl; - out << "class " << component << "_Profiler {" << endl; - out << "public:" << endl; - out << " " << component << "_Profiler();" << endl; - out << " void setVersion(int version);" << endl; - out << " void countTransition(" << component << "_State state, " << component << "_Event event);" << endl; - out << " void possibleTransition(" << component << "_State state, " << component << "_Event event);" << endl; - out << " void dumpStats(ostream& out) const;" << endl; - out << " void clearStats();" << endl; - out << "private:" << endl; - out << " int m_counters[" << component << "_State_NUM][" << component << "_Event_NUM];" << endl; - out << " int m_event_counters[" << component << "_Event_NUM];" << endl; - out << " bool m_possible[" << component << "_State_NUM][" << component << "_Event_NUM];" << endl; - out << " int m_version;" << endl; - out << "};" << endl; - out << "#endif // " << component << "_PROFILER_H" << endl; -} - -void StateMachine::printProfilerC(ostream& out, string component) -{ - out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << "// " << getIdent() << ": " << getShorthand() << endl; - out << endl; - out << "#include \"mem/protocol/" << component << "_Profiler.hh\"" << endl; - out << endl; - - // Constructor - out << component << "_Profiler::" << component << "_Profiler()" << endl; - out << "{" << endl; - out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " m_possible[state][event] = false;" << endl; - out << " m_counters[state][event] = 0;" << endl; - out << " }" << endl; - out << " }" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " m_event_counters[event] = 0;" << endl; - out << " }" << endl; - out << "}" << endl; - - // setVersion - out << "void " << component << "_Profiler::setVersion(int version)" << endl; - out << "{" << endl; - out << " m_version = version;" << endl; - out << "}" << endl; - - // Clearstats - out << "void " << component << "_Profiler::clearStats()" << endl; - out << "{" << endl; - out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " m_counters[state][event] = 0;" << endl; - out << " }" << endl; - out << " }" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " m_event_counters[event] = 0;" << endl; - out << " }" << endl; - out << "}" << endl; - - // Count Transition - out << "void " << component << "_Profiler::countTransition(" << component << "_State state, " << component << "_Event event)" << endl; - out << "{" << endl; - out << " assert(m_possible[state][event]);" << endl; - out << " m_counters[state][event]++;" << endl; - out << " m_event_counters[event]++;" << endl; - out << "}" << endl; - - // Possible Transition - out << "void " << component << "_Profiler::possibleTransition(" << component << "_State state, " << component << "_Event event)" << endl; - out << "{" << endl; - out << " m_possible[state][event] = true;" << endl; - out << "}" << endl; - - // dumpStats - out << "void " << component << "_Profiler::dumpStats(ostream& out) const" << endl; - out << "{" << endl; - out << " out << \" --- " << component << " \" << m_version << \" ---\" << endl;" << endl; - out << " out << \" - Event Counts -\" << endl;" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " int count = m_event_counters[event];" << endl; - out << " out << (" << component << "_Event) event << \" \" << count << endl;" << endl; - out << " }" << endl; - out << " out << endl;" << endl; - out << " out << \" - Transitions -\" << endl;" << endl; - out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl; - out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl; - out << " if (m_possible[state][event]) {" << endl; - out << " int count = m_counters[state][event];" << endl; - out << " out << (" << component << "_State) state << \" \" << (" << component << "_Event) event << \" \" << count;" << endl; - out << " if (count == 0) {" << endl; - out << " out << \" <-- \";" << endl; - out << " }" << endl; - out << " out << endl;" << endl; - out << " }" << endl; - out << " }" << endl; - out << " out << endl;" << endl; - out << " }" << endl; - out << "}" << endl; -} - - - -// ************************** // -// ******* HTML Files ******* // -// ************************** // - -string frameRef(string click_href, string click_target, string over_href, string over_target_num, string text) -{ - string temp; - temp += ""; - return temp; -} - -string frameRef(string href, string target, string target_num, string text) -{ - return frameRef(href, target, href, target_num, text); -} - - -void StateMachine::writeHTMLFiles(string path) -{ - string filename; - string component = getIdent(); - - /* - { - ostringstream out; - out << "" << endl; - out << "" << endl; - out << "" << component << "" << endl; - out << "" << endl; - out << "" << endl; - out << " " << endl; - out << " " << endl; - out << "" << endl; - out << "" << endl; - conditionally_write_file(path + component + ".html", out); - } - */ - - // Create table with no row hilighted - { - ostringstream out; - printHTMLTransitions(out, numStates()+1); - - // -- Write file - filename = component + "_table.html"; - conditionally_write_file(path + filename, out); - } - - // Generate transition tables - for(int i=0; i" << endl; - - // -- Header - out << "

" << formatHTMLShorthand(getShorthand()) << ": " << endl; - Vector machine_vec = g_sym_table.getStateMachines(); - for (int i=0; igetIdent() << endl; - } else { - out << "getIdent() + "_table.html\">" + type->getIdent() + " " << endl; - } - } - out << "

" << endl; - - // -- Table header - out << "" << endl; - - // -- Column headers - out << "" << endl; - - // -- First column header - out << " " << endl; - - for(int event = 0; event < numEvents(); event++ ) { - out << " " << endl; - } - - out << "" << endl; - - // -- Body of table - for(int state = 0; state < numStates(); state++ ) { - out << "" << endl; - - // -- Each row - if (state == active_state) { - out << " " << endl; - - // -- One column for each event - for(int event = 0; event < numEvents(); event++ ) { - const Transition* trans_ptr = getTransPtr(state, event); - - if( trans_ptr != NULL ) { - bool stall_action = false; - string nextState; - string actions_str; - - // -- Get the actions - // actions = trans_ptr->getActionShorthands(); - const Vector actions = trans_ptr->getActions(); - for (int action=0; action < actions.size(); action++) { - if ((actions[action]->getIdent() == "z_stall") || - (actions[action]->getIdent() == "zz_recycleMandatoryQueue")) { - stall_action = true; - } - actions_str += " "; - actions_str += frameRef(getIdent() + "_action_" + actions[action]->getIdent() + ".html", "Status", "1", - formatHTMLShorthand(actions[action]->getShorthand())); - actions_str += "\n"; - } - - // -- Get the next state - if (trans_ptr->getNextStatePtr()->getIdent() != getState(state).getIdent()) { - string click_href = getIdent() + "_table_" + trans_ptr->getNextStatePtr()->getIdent() + ".html"; - nextState = frameRef(click_href, "Table", getIdent() + "_State_" + trans_ptr->getNextStatePtr()->getIdent() + ".html", "1", - formatHTMLShorthand(trans_ptr->getNextStateShorthand())); - } else { - nextState = ""; - } - - // -- Print out "actions/next-state" - if (stall_action) { - if (state == active_state) { - out << " " << endl; - } else { - // This is the no transition case - if (state == active_state) { - out << " " << endl; - } else { - out << " " << endl; - } - } - } - // -- Each row - if (state == active_state) { - out << " " << endl; - - out << "" << endl; - } - - // -- Column footer - out << "" << endl; - out << " " << endl; - - for(int i = 0; i < numEvents(); i++ ) { - out << " " << endl; - } - out << "" << endl; - - // -- Epilog - out << "
"; - out << frameRef(getIdent() + "_Event_" + getEvent(event).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(event).getShorthand())); - out << "
"; - } else { - out << " "; - } - - string click_href = getIdent() + "_table_" + getState(state).getIdent() + ".html"; - string text = formatHTMLShorthand(getState(state).getShorthand()); - - out << frameRef(click_href, "Table", getIdent() + "_State_" + getState(state).getIdent() + ".html", "1", formatHTMLShorthand(getState(state).getShorthand())); - out << ""; - } else { - out << " "; - } - } else if (active_state < numStates() && (trans_ptr->getNextStatePtr()->getIdent() == getState(active_state).getIdent())) { - out << " "; - } else if (state == active_state) { - out << " "; - } else { - out << " "; - } - - out << actions_str; - if ((nextState.length() != 0) && (actions_str.length() != 0)) { - out << "/"; - } - out << nextState; - out << "  "; - } else { - out << " "; - } - - click_href = getIdent() + "_table_" + getState(state).getIdent() + ".html"; - text = formatHTMLShorthand(getState(state).getShorthand()); - - out << frameRef(click_href, "Table", getIdent() + "_State_" + getState(state).getIdent() + ".html", "1", formatHTMLShorthand(getState(state).getShorthand())); - out << "
"; - out << frameRef(getIdent() + "_Event_" + getEvent(i).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(i).getShorthand())); - out << "
" << endl; - out << "" << endl; -} - - diff --git a/src/mem/slicc/symbols/StateMachine.hh b/src/mem/slicc/symbols/StateMachine.hh deleted file mode 100644 index f5f3ab073b..0000000000 --- a/src/mem/slicc/symbols/StateMachine.hh +++ /dev/null @@ -1,156 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#ifndef STATEMACHINE_H -#define STATEMACHINE_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Vector.hh" -#include "mem/gems_common/Map.hh" -#include "mem/slicc/symbols/Symbol.hh" -#include - -using namespace std; - -class Transition; -class Event; -class State; -class Action; -class Var; -class Func; -class FormalParamAST; - -class StateMachine : public Symbol { -public: - // Constructors - StateMachine(string ident, const Location& location, const Map& pairs, Vector* config_parameters); - - // Destructor - ~StateMachine(); - - // Public Methods - - // Add items to the state machine - // void setMachine(string ident, const Map& pairs); - void addState(State* state_ptr); - void addEvent(Event* event_ptr); - void addAction(Action* action_ptr); - void addTransition(Transition* trans_ptr); - void addInPort(Var* var) { m_in_ports.insertAtBottom(var); } - void addFunc(Func* func); - void addObj(Var* obj) { m_objs.insertAtBottom(obj); } - - // Accessors to vectors - const State& getState(int index) const { return *m_states[index]; } - const Event& getEvent(int index) const { return *m_events[index]; } - const Action& getAction(int index) const { return *m_actions[index]; } - const Transition& getTransition(int index) const { return *m_transitions[index]; } - const Transition* getTransPtr(int stateIndex, int eventIndex) const; - const Var& getObject(int index) const { return *m_objs[index]; } - - // Accessors for size of vectors - int numStates() const { return m_states.size(); } - int numEvents() const { return m_events.size(); } - int numActions() const { return m_actions.size(); } - int numTransitions() const { return m_transitions.size(); } - int numObjects() const { return m_objs.size(); } - - void buildTable(); // Needs to be called before accessing the table - - // Code generator methods - void writeCFiles(string path) ; - void writeHTMLFiles(string path) ; - - void print(ostream& out) const { out << "[StateMachine: " << toString() << "]" << endl; } -private: - - Vector* m_config_parameters; - - // Private Methods - void checkForDuplicate(const Symbol& sym) const; - - int getStateIndex(State* state_ptr) const { return m_state_map.lookup(state_ptr); } - int getEventIndex(Event* event_ptr) const { return m_event_map.lookup(event_ptr); } - - // Private copy constructor and assignment operator - // StateMachine(const StateMachine& obj); - // StateMachine& operator=(const StateMachine& obj); - - void printControllerH(ostream& out, string component) ; - void printControllerC(ostream& out, string component) ; - void printCWakeup(ostream& out, string component) ; - void printCSwitch(ostream& out, string component) ; - void printProfilerH(ostream& out, string component) ; - void printProfilerC(ostream& out, string component) ; - - void printHTMLTransitions(ostream& out, int active_state) ; - - // Data Members (m_ prefix) - Vector m_states; - Vector m_events; - Vector m_actions; - Vector m_transitions; - Vector m_internal_func_vec; - - Map m_state_map; - Map m_event_map; - - Vector m_in_ports; - - Vector m_objs; - - // Table variables - bool m_table_built; - Vector > m_table; - - //added by SS - std::vector m_message_buffer_names; - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const StateMachine& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const StateMachine& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //STATEMACHINE_H diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py new file mode 100644 index 0000000000..e54d6a435d --- /dev/null +++ b/src/mem/slicc/symbols/StateMachine.py @@ -0,0 +1,1222 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter, orderdict + +from slicc.symbols.Symbol import Symbol +from slicc.symbols.Var import Var +import slicc.generate.html as html + +class StateMachine(Symbol): + def __init__(self, symtab, ident, location, pairs, config_parameters): + super(StateMachine, self).__init__(symtab, ident, location, pairs) + self.table = None + self.config_parameters = config_parameters + for param in config_parameters: + var = Var(symtab, param.name, location, param.type_ast.type, + "m_%s" % param.name, {}, self) + self.symtab.registerSym(param.name, var) + + self.states = orderdict() + self.events = orderdict() + self.actions = orderdict() + self.transitions = [] + self.in_ports = [] + self.functions = [] + self.objects = [] + + self.message_buffer_names = [] + + def __repr__(self): + return "[StateMachine: %s]" % self.ident + + def addState(self, state): + assert self.table is None + self.states[state.ident] = state + + def addEvent(self, event): + assert self.table is None + self.events[event.ident] = event + + def addAction(self, action): + assert self.table is None + + # Check for duplicate action + for other in self.actions.itervalues(): + if action.ident == other.ident: + a.warning("Duplicate action definition: %s" % a.ident) + action.error("Duplicate action definition: %s" % action.ident) + if action.short == other.short: + other.warning("Duplicate action shorthand: %s" % other.ident) + other.warning(" shorthand = %s" % other.short) + action.warning("Duplicate action shorthand: %s" % action.ident) + action.error(" shorthand = %s" % action.short) + + self.actions[action.ident] = action + + def addTransition(self, trans): + assert self.table is None + self.transitions.append(trans) + + def addInPort(self, var): + self.in_ports.append(var) + + def addFunc(self, func): + # register func in the symbol table + self.symtab.registerSym(str(func), func) + self.functions.append(func) + + def addObject(self, obj): + self.objects.append(obj) + + # Needs to be called before accessing the table + def buildTable(self): + assert self.table is None + + table = {} + + for trans in self.transitions: + # Track which actions we touch so we know if we use them + # all -- really this should be done for all symbols as + # part of the symbol table, then only trigger it for + # Actions, States, Events, etc. + + for action in trans.actions: + action.used = True + + index = (trans.state, trans.event) + if index in table: + table[index].warning("Duplicate transition: %s" % table[index]) + trans.error("Duplicate transition: %s" % trans) + table[index] = trans + + # Look at all actions to make sure we used them all + for action in self.actions.itervalues(): + if not action.used: + error_msg = "Unused action: %s" % action.ident + if "desc" in action: + error_msg += ", " + action.desc + action.warning(error_msg) + self.table = table + + def writeCodeFiles(self, path): + self.printControllerHH(path) + self.printControllerCC(path) + self.printCSwitch(path) + self.printCWakeup(path) + self.printProfilerCC(path) + self.printProfilerHH(path) + + for func in self.functions: + func.writeCodeFiles(path) + + def printControllerHH(self, path): + '''Output the method declarations for the class declaration''' + code = code_formatter() + ident = self.ident + c_ident = "%s_Controller" % self.ident + + self.message_buffer_names = [] + + code(''' +/** \\file $ident.hh + * + * Auto generated C++ code started by $__file__:$__line__ + * Created by slicc definition of Module "${{self.short}}" + */ + +#ifndef ${ident}_CONTROLLER_H +#define ${ident}_CONTROLLER_H + +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/Consumer.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/protocol/TransitionResult.hh" +#include "mem/protocol/Types.hh" +#include "mem/protocol/${ident}_Profiler.hh" +''') + + seen_types = set() + for var in self.objects: + if var.type.ident not in seen_types: + code('#include "mem/protocol/${{var.type.c_ident}}.hh"') + seen_types.add(var.type.ident) + + # for adding information to the protocol debug trace + code(''' +extern stringstream ${ident}_transitionComment; + +class $c_ident : public AbstractController { +#ifdef CHECK_COHERENCE +#endif /* CHECK_COHERENCE */ +public: + $c_ident(const string & name); + static int getNumControllers(); + void init(Network* net_ptr, const vector & argv); + MessageBuffer* getMandatoryQueue() const; + const int & getVersion() const; + const string toString() const; + const string getName() const; + const MachineType getMachineType() const; + void print(ostream& out) const; + void printConfig(ostream& out) const; + void wakeup(); + void set_atomic(Address addr); + void started_writes(); + void clear_atomic(); + void printStats(ostream& out) const { s_profiler.dumpStats(out); } + void clearStats() { s_profiler.clearStats(); } +private: +''') + + code.indent() + # added by SS + for param in self.config_parameters: + code('int m_${{param.ident}};') + + if self.ident == "L1Cache": + code(''' +int servicing_atomic; +bool started_receiving_writes; +Address locked_read_request1; +Address locked_read_request2; +Address locked_read_request3; +Address locked_read_request4; +int read_counter; +''') + + code(''' +int m_number_of_TBEs; + +TransitionResult doTransition(${ident}_Event event, ${ident}_State state, const Address& addr); // in ${ident}_Transitions.cc +TransitionResult doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr); // in ${ident}_Transitions.cc +string m_name; +int m_transitions_per_cycle; +int m_buffer_size; +int m_recycle_latency; +map< string, string > m_cfg; +NodeID m_version; +Network* m_net_ptr; +MachineID m_machineID; +${ident}_Profiler s_profiler; +static int m_num_controllers; +// Internal functions +''') + + for func in self.functions: + proto = func.prototype + if proto: + code('$proto') + + code(''' + +// Actions +''') + for action in self.actions.itervalues(): + code('/** \\brief ${{action.desc}} */') + code('void ${{action.ident}}(const Address& addr);') + + # the controller internal variables + code(''' + +// Object +''') + for var in self.objects: + th = var.get("template_hack", "") + code('${{var.type.c_ident}}$th* m_${{var.c_ident}}_ptr;') + + if var.type.ident == "MessageBuffer": + self.message_buffer_names.append("m_%s_ptr" % var.c_ident) + + code.dedent() + code('};') + code('#endif // ${ident}_CONTROLLER_H') + code.write(path, '%s.hh' % c_ident) + + def printControllerCC(self, path): + '''Output the actions for performing the actions''' + + code = code_formatter() + ident = self.ident + c_ident = "%s_Controller" % self.ident + + code(''' +/** \\file $ident.cc + * + * Auto generated C++ code started by $__file__:$__line__ + * Created by slicc definition of Module "${{self.short}}" + */ + +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" +#include "mem/protocol/${ident}_Controller.hh" +#include "mem/protocol/${ident}_State.hh" +#include "mem/protocol/${ident}_Event.hh" +#include "mem/protocol/Types.hh" +#include "mem/ruby/system/System.hh" +''') + + # include object classes + seen_types = set() + for var in self.objects: + if var.type.ident not in seen_types: + code('#include "mem/protocol/${{var.type.c_ident}}.hh"') + seen_types.add(var.type.ident) + + code(''' +int $c_ident::m_num_controllers = 0; + +stringstream ${ident}_transitionComment; +#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str) +/** \\brief constructor */ +$c_ident::$c_ident(const string &name) + : m_name(name) +{ +''') + code.indent() + if self.ident == "L1Cache": + code(''' +servicing_atomic = 0; +started_receiving_writes = false; +locked_read_request1 = Address(-1); +locked_read_request2 = Address(-1); +locked_read_request3 = Address(-1); +locked_read_request4 = Address(-1); +read_counter = 0; +''') + + code('m_num_controllers++;') + for var in self.objects: + if var.ident.find("mandatoryQueue") >= 0: + code('m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();') + + code.dedent() + code(''' +} + +void $c_ident::init(Network *net_ptr, const vector &argv) +{ + for (size_t i = 0; i < argv.size(); i += 2) { + if (argv[i] == "version") + m_version = atoi(argv[i+1].c_str()); + else if (argv[i] == "transitions_per_cycle") + m_transitions_per_cycle = atoi(argv[i+1].c_str()); + else if (argv[i] == "buffer_size") + m_buffer_size = atoi(argv[i+1].c_str()); + else if (argv[i] == "recycle_latency") + m_recycle_latency = atoi(argv[i+1].c_str()); + else if (argv[i] == "number_of_TBEs") + m_number_of_TBEs = atoi(argv[i+1].c_str()); +''') + + code.indent() + code.indent() + for param in self.config_parameters: + code('else if (argv[i] == "${{param.name}}")') + if param.type_ast.type.ident == "int": + code(' m_${{param.name}} = atoi(argv[i+1].c_str());') + else: + self.error("only int parameters are supported right now") + code.dedent() + code.dedent() + code(''' + } + + m_net_ptr = net_ptr; + m_machineID.type = MachineType_${ident}; + m_machineID.num = m_version; + for (size_t i = 0; i < argv.size(); i += 2) { + if (argv[i] != "version") + m_cfg[argv[i]] = argv[i+1]; + } + + // Objects + s_profiler.setVersion(m_version); +''') + + code.indent() + for var in self.objects: + vtype = var.type + vid = "m_%s_ptr" % var.c_ident + if "network" not in var: + # Not a network port object + if "primitive" in vtype: + code('$vid = new ${{vtype.c_ident}};') + if "default" in var: + code('(*$vid) = ${{var["default"]}};') + else: + # Normal Object + # added by SS + if "factory" in var: + code('$vid = ${{var["factory"]}};') + elif var.ident.find("mandatoryQueue") < 0: + th = var.get("template_hack", "") + expr = "%s = new %s%s" % (vid, vtype.c_ident, th) + + args = "" + if "non_obj" not in vtype and not vtype.isEnumeration: + if expr.find("TBETable") >= 0: + args = "m_number_of_TBEs" + else: + args = var.get("constructor_hack", "") + args = "(%s)" % args + + code('$expr$args;') + else: + code(';') + + code('assert($vid != NULL);') + + if "default" in var: + code('(*$vid) = ${{var["default"]}}; // Object default') + elif "default" in vtype: + code('(*$vid) = ${{vtype["default"]}}; // Type ${{vtype.ident}} default') + + # Set ordering + if "ordered" in var and "trigger_queue" not in var: + # A buffer + code('$vid->setOrdering(${{var["ordered"]}});') + + # Set randomization + if "random" in var: + # A buffer + code('$vid->setRandomization(${{var["random"]}});') + + # Set Priority + if vtype.isBuffer and \ + "rank" in var and "trigger_queue" not in var: + code('$vid->setPriority(${{var["rank"]}});') + else: + # Network port object + network = var["network"] + ordered = var["ordered"] + vnet = var["virtual_network"] + + assert var.machine is not None + code(''' +$vid = m_net_ptr->get${network}NetQueue(m_version+MachineType_base_number(string_to_MachineType("${{var.machine.ident}}")), $ordered, $vnet); +''') + + code('assert($vid != NULL);') + + # Set ordering + if "ordered" in var: + # A buffer + code('$vid->setOrdering(${{var["ordered"]}});') + + # Set randomization + if "random" in var: + # A buffer + code('$vid->setRandomization(${{var["random"]}})') + + # Set Priority + if "rank" in var: + code('$vid->setPriority(${{var["rank"]}})') + + # Set buffer size + if vtype.isBuffer: + code(''' +if (m_buffer_size > 0) { + $vid->setSize(m_buffer_size); +} +''') + + # set description (may be overriden later by port def) + code('$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");') + + # Set the queue consumers + code.insert_newline() + for port in self.in_ports: + code('${{port.code}}.setConsumer(this);') + + # Set the queue descriptions + code.insert_newline() + for port in self.in_ports: + code('${{port.code}}.setDescription("[Version " + int_to_string(m_version) + ", $ident, $port]");') + + # Initialize the transition profiling + code.insert_newline() + for trans in self.transitions: + # Figure out if we stall + stall = False + for action in trans.actions: + if action.ident == "z_stall": + stall = True + + # Only possible if it is not a 'z' case + if not stall: + state = "%s_State_%s" % (self.ident, trans.state.ident) + event = "%s_Event_%s" % (self.ident, trans.event.ident) + code('s_profiler.possibleTransition($state, $event);') + + # added by SS to initialize recycle_latency of message buffers + for buf in self.message_buffer_names: + code("$buf->setRecycleLatency(m_recycle_latency);") + + code.dedent() + code('}') + + has_mandatory_q = False + for port in self.in_ports: + if port.code.find("mandatoryQueue_ptr") >= 0: + has_mandatory_q = True + + if has_mandatory_q: + mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident + else: + mq_ident = "NULL" + + code(''' +int $c_ident::getNumControllers() { + return m_num_controllers; +} + +MessageBuffer* $c_ident::getMandatoryQueue() const { + return $mq_ident; +} + +const int & $c_ident::getVersion() const{ + return m_version; +} + +const string $c_ident::toString() const{ + return "$c_ident"; +} + +const string $c_ident::getName() const{ + return m_name; +} +const MachineType $c_ident::getMachineType() const{ + return MachineType_${ident}; +} + +void $c_ident::print(ostream& out) const { out << "[$c_ident " << m_version << "]"; } + +void $c_ident::printConfig(ostream& out) const { + out << "$c_ident config: " << m_name << endl; + out << " version: " << m_version << endl; + for (map::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) { + out << " " << (*it).first << ": " << (*it).second << endl; + } +} + +// Actions +''') + + for action in self.actions.itervalues(): + if "c_code" not in action: + continue + + code(''' +/** \\brief ${{action.desc}} */ +void $c_ident::${{action.ident}}(const Address& addr) +{ + DEBUG_MSG(GENERATED_COMP, HighPrio, "executing"); + ${{action["c_code"]}} +} + +''') + code.write(path, "%s.cc" % c_ident) + + def printCWakeup(self, path): + '''Output the wakeup loop for the events''' + + code = code_formatter() + ident = self.ident + + code(''' +// Auto generated C++ code started by $__file__:$__line__ +// ${ident}: ${{self.short}} + +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" +#include "mem/protocol/${ident}_Controller.hh" +#include "mem/protocol/${ident}_State.hh" +#include "mem/protocol/${ident}_Event.hh" +#include "mem/protocol/Types.hh" +#include "mem/ruby/system/System.hh" + +void ${ident}_Controller::wakeup() +{ + + int counter = 0; + while (true) { + // Some cases will put us into an infinite loop without this limit + assert(counter <= m_transitions_per_cycle); + if (counter == m_transitions_per_cycle) { + g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we\'re fully utilized + g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again + break; + } +''') + + code.indent() + code.indent() + + # InPorts + # + # Find the position of the mandatory queue in the vector so + # that we can print it out first + + mandatory_q = None + if self.ident == "L1Cache": + for i,port in enumerate(self.in_ports): + assert "c_code_in_port" in port + if str(port).find("mandatoryQueue_in") >= 0: + assert mandatory_q is None + mandatory_q = port + + assert mandatory_q is not None + + # print out the mandatory queue here + port = mandatory_q + code('// ${ident}InPort $port') + output = port["c_code_in_port"] + + pos = output.find("TransitionResult result = doTransition((L1Cache_mandatory_request_type_to_event(((*in_msg_ptr)).m_Type)), L1Cache_getState(addr), addr);") + assert pos >= 0 + atomics_string = ''' +if ((((*in_msg_ptr)).m_Type) == CacheRequestType_ATOMIC) { + if (servicing_atomic == 0) { + if (locked_read_request1 == Address(-1)) { + assert(read_counter == 0); + locked_read_request1 = addr; + assert(read_counter == 0); + read_counter++; + } + else if (addr == locked_read_request1) { + ; // do nothing + } + else { + assert(0); // should never be here if servicing one request at a time + } + } + else if (!started_receiving_writes) { + if (servicing_atomic == 1) { + if (locked_read_request2 == Address(-1)) { + assert(locked_read_request1 != Address(-1)); + assert(read_counter == 1); + locked_read_request2 = addr; + assert(read_counter == 1); + read_counter++; + } + else if (addr == locked_read_request2) { + ; // do nothing + } + else { + assert(0); // should never be here if servicing one request at a time + } + } + else if (servicing_atomic == 2) { + if (locked_read_request3 == Address(-1)) { + assert(locked_read_request1 != Address(-1)); + assert(locked_read_request2 != Address(-1)); + assert(read_counter == 1); + locked_read_request3 = addr; + assert(read_counter == 2); + read_counter++; + } + else if (addr == locked_read_request3) { + ; // do nothing + } + else { + assert(0); // should never be here if servicing one request at a time + } + } + else if (servicing_atomic == 3) { + if (locked_read_request4 == Address(-1)) { + assert(locked_read_request1 != Address(-1)); + assert(locked_read_request2 != Address(-1)); + assert(locked_read_request3 != Address(-1)); + assert(read_counter == 1); + locked_read_request4 = addr; + assert(read_counter == 3); + read_counter++; + } + else if (addr == locked_read_request4) { + ; // do nothing + } + else { + assert(0); // should never be here if servicing one request at a time + } + } + else { + assert(0); + } + } +} +else { + if (servicing_atomic > 0) { + // reset + servicing_atomic = 0; + read_counter = 0; + started_receiving_writes = false; + locked_read_request1 = Address(-1); + locked_read_request2 = Address(-1); + locked_read_request3 = Address(-1); + locked_read_request4 = Address(-1); + } +} +''' + + output = output[:pos] + atomics_string + output[pos:] + code('$output') + + for port in self.in_ports: + # don't print out mandatory queue twice + if port == mandatory_q: + continue + + if ident == "L1Cache": + if str(port).find("forwardRequestNetwork_in") >= 0: + code(''' +bool postpone = false; +if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) { + const RequestMsg* in_msg_ptr; + in_msg_ptr = dynamic_cast(((*m_L1Cache_forwardToCache_ptr)).peek()); + if ((((servicing_atomic == 1) && (locked_read_request1 == ((*in_msg_ptr)).m_Address)) || + ((servicing_atomic == 2) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address)) || + ((servicing_atomic == 3) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address)) || + ((servicing_atomic == 4) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) { + postpone = true; + } +} +if (!postpone) { +''') + code.indent() + code('// ${ident}InPort $port') + code('${{port["c_code_in_port"]}}') + code.dedent() + + if ident == "L1Cache": + if str(port).find("forwardRequestNetwork_in") >= 0: + code.dedent() + code('}') + code.indent() + code('') + + code.dedent() + code.dedent() + code(''' + break; // If we got this far, we have nothing left todo + } +} +''') + + if self.ident == "L1Cache": + code(''' +void ${ident}_Controller::set_atomic(Address addr) +{ + servicing_atomic++; +} + +void ${ident}_Controller::started_writes() +{ + started_receiving_writes = true; +} + +void ${ident}_Controller::clear_atomic() +{ + assert(servicing_atomic > 0); + read_counter--; + servicing_atomic--; + if (read_counter == 0) { + servicing_atomic = 0; + started_receiving_writes = false; + locked_read_request1 = Address(-1); + locked_read_request2 = Address(-1); + locked_read_request3 = Address(-1); + locked_read_request4 = Address(-1); + } +} +''') + else: + code(''' +void ${ident}_Controller::started_writes() +{ + assert(0); +} + +void ${ident}_Controller::set_atomic(Address addr) +{ + assert(0); +} + +void ${ident}_Controller::clear_atomic() +{ + assert(0); +} +''') + + + code.write(path, "%s_Wakeup.cc" % self.ident) + + def printCSwitch(self, path): + '''Output switch statement for transition table''' + + code = code_formatter() + ident = self.ident + + code(''' +// Auto generated C++ code started by $__file__:$__line__ +// ${ident}: ${{self.short}} + +#include "mem/ruby/common/Global.hh" +#include "mem/protocol/${ident}_Controller.hh" +#include "mem/protocol/${ident}_State.hh" +#include "mem/protocol/${ident}_Event.hh" +#include "mem/protocol/Types.hh" +#include "mem/ruby/system/System.hh" + +#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event)) + +#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str()) +#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str("")) + +TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident}_State state, const Address& addr +) +{ + ${ident}_State next_state = state; + + DEBUG_NEWLINE(GENERATED_COMP, MedPrio); + DEBUG_MSG(GENERATED_COMP, MedPrio, *this); + DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime()); + DEBUG_EXPR(GENERATED_COMP, MedPrio,state); + DEBUG_EXPR(GENERATED_COMP, MedPrio,event); + DEBUG_EXPR(GENERATED_COMP, MedPrio,addr); + + TransitionResult result = doTransitionWorker(event, state, next_state, addr); + + if (result == TransitionResult_Valid) { + DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state); + DEBUG_NEWLINE(GENERATED_COMP, MedPrio); + s_profiler.countTransition(state, event); + if (Debug::getProtocolTrace()) { + g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, + ${ident}_State_to_string(state), + ${ident}_Event_to_string(event), + ${ident}_State_to_string(next_state), GET_TRANSITION_COMMENT()); + } + CLEAR_TRANSITION_COMMENT(); + ${ident}_setState(addr, next_state); + + } else if (result == TransitionResult_ResourceStall) { + if (Debug::getProtocolTrace()) { + g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, + ${ident}_State_to_string(state), + ${ident}_Event_to_string(event), + ${ident}_State_to_string(next_state), + "Resource Stall"); + } + } else if (result == TransitionResult_ProtocolStall) { + DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling"); + DEBUG_NEWLINE(GENERATED_COMP, MedPrio); + if (Debug::getProtocolTrace()) { + g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, + ${ident}_State_to_string(state), + ${ident}_Event_to_string(event), + ${ident}_State_to_string(next_state), + "Protocol Stall"); + } + } + + return result; +} + +TransitionResult ${ident}_Controller::doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr +) +{ + switch(HASH_FUN(state, event)) { +''') + + # This map will allow suppress generating duplicate code + cases = orderdict() + + for trans in self.transitions: + case_string = "%s_State_%s, %s_Event_%s" % \ + (self.ident, trans.state.ident, self.ident, trans.event.ident) + + case = code_formatter() + # Only set next_state if it changes + if trans.state != trans.nextState: + ns_ident = trans.nextState.ident + case('next_state = ${ident}_State_${ns_ident};') + + actions = trans.actions + + # Check for resources + case_sorter = [] + res = trans.resources + for key,val in res.iteritems(): + if key.type.ident != "DNUCAStopTable": + val = ''' +if (!%s.areNSlotsAvailable(%s)) { + return TransitionResult_ResourceStall; +} +''' % (key.code, val) + case_sorter.append(val) + + + # Emit the code sequences in a sorted order. This makes the + # output deterministic (without this the output order can vary + # since Map's keys() on a vector of pointers is not deterministic + for c in sorted(case_sorter): + case("$c") + + # Figure out if we stall + stall = False + for action in actions: + if action.ident == "z_stall": + stall = True + break + + if stall: + case('return TransitionResult_ProtocolStall;') + else: + for action in actions: + case('${{action.ident}}(addr);') + case('return TransitionResult_Valid;') + + case = str(case) + + # Look to see if this transition code is unique. + if case not in cases: + cases[case] = [] + + cases[case].append(case_string) + + # Walk through all of the unique code blocks and spit out the + # corresponding case statement elements + for case,transitions in cases.iteritems(): + # Iterative over all the multiple transitions that share + # the same code + for trans in transitions: + code(' case HASH_FUN($trans):') + code(' {') + code(' $case') + code(' }') + + code(''' + default: + WARN_EXPR(m_version); + WARN_EXPR(g_eventQueue_ptr->getTime()); + WARN_EXPR(addr); + WARN_EXPR(event); + WARN_EXPR(state); + ERROR_MSG(\"Invalid transition\"); + } + return TransitionResult_Valid; +} +''') + code.write(path, "%s_Transitions.cc" % self.ident) + + def printProfilerHH(self, path): + code = code_formatter() + ident = self.ident + + code(''' +// Auto generated C++ code started by $__file__:$__line__ +// ${ident}: ${{self.short}} + +#ifndef ${ident}_PROFILER_H +#define ${ident}_PROFILER_H + +#include "mem/ruby/common/Global.hh" +#include "mem/protocol/${ident}_State.hh" +#include "mem/protocol/${ident}_Event.hh" + +class ${ident}_Profiler { + public: + ${ident}_Profiler(); + void setVersion(int version); + void countTransition(${ident}_State state, ${ident}_Event event); + void possibleTransition(${ident}_State state, ${ident}_Event event); + void dumpStats(ostream& out) const; + void clearStats(); + + private: + int m_counters[${ident}_State_NUM][${ident}_Event_NUM]; + int m_event_counters[${ident}_Event_NUM]; + bool m_possible[${ident}_State_NUM][${ident}_Event_NUM]; + int m_version; +}; + +#endif // ${ident}_PROFILER_H +''') + code.write(path, "%s_Profiler.hh" % self.ident) + + def printProfilerCC(self, path): + code = code_formatter() + ident = self.ident + + code(''' +// Auto generated C++ code started by $__file__:$__line__ +// ${ident}: ${{self.short}} + +#include "mem/protocol/${ident}_Profiler.hh" + +${ident}_Profiler::${ident}_Profiler() +{ + for (int state = 0; state < ${ident}_State_NUM; state++) { + for (int event = 0; event < ${ident}_Event_NUM; event++) { + m_possible[state][event] = false; + m_counters[state][event] = 0; + } + } + for (int event = 0; event < ${ident}_Event_NUM; event++) { + m_event_counters[event] = 0; + } +} +void ${ident}_Profiler::setVersion(int version) +{ + m_version = version; +} +void ${ident}_Profiler::clearStats() +{ + for (int state = 0; state < ${ident}_State_NUM; state++) { + for (int event = 0; event < ${ident}_Event_NUM; event++) { + m_counters[state][event] = 0; + } + } + + for (int event = 0; event < ${ident}_Event_NUM; event++) { + m_event_counters[event] = 0; + } +} +void ${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event) +{ + assert(m_possible[state][event]); + m_counters[state][event]++; + m_event_counters[event]++; +} +void ${ident}_Profiler::possibleTransition(${ident}_State state, ${ident}_Event event) +{ + m_possible[state][event] = true; +} +void ${ident}_Profiler::dumpStats(ostream& out) const +{ + out << " --- ${ident} " << m_version << " ---" << endl; + out << " - Event Counts -" << endl; + for (int event = 0; event < ${ident}_Event_NUM; event++) { + int count = m_event_counters[event]; + out << (${ident}_Event) event << " " << count << endl; + } + out << endl; + out << " - Transitions -" << endl; + for (int state = 0; state < ${ident}_State_NUM; state++) { + for (int event = 0; event < ${ident}_Event_NUM; event++) { + if (m_possible[state][event]) { + int count = m_counters[state][event]; + out << (${ident}_State) state << " " << (${ident}_Event) event << " " << count; + if (count == 0) { + out << " <-- "; + } + out << endl; + } + } + out << endl; + } +} +''') + code.write(path, "%s_Profiler.cc" % self.ident) + + # ************************** + # ******* HTML Files ******* + # ************************** + def frameRef(self, click_href, click_target, over_href, over_target_num, + text): + code = code_formatter(fix_newlines=False) + code("""${{html.formatShorthand(text)}}""") + return str(code) + + def writeHTMLFiles(self, path): + # Create table with no row hilighted + self.printHTMLTransitions(path, None) + + # Generate transition tables + for state in self.states.itervalues(): + self.printHTMLTransitions(path, state) + + # Generate action descriptions + for action in self.actions.itervalues(): + name = "%s_action_%s.html" % (self.ident, action.ident) + code = html.createSymbol(action, "Action") + code.write(path, name) + + # Generate state descriptions + for state in self.states.itervalues(): + name = "%s_State_%s.html" % (self.ident, state.ident) + code = html.createSymbol(state, "State") + code.write(path, name) + + # Generate event descriptions + for event in self.events.itervalues(): + name = "%s_Event_%s.html" % (self.ident, event.ident) + code = html.createSymbol(event, "Event") + code.write(path, name) + + def printHTMLTransitions(self, path, active_state): + code = code_formatter() + + code(''' + + +

${{html.formatShorthand(self.short)}}: +''') + code.indent() + for i,machine in enumerate(self.symtab.getAllType(StateMachine)): + mid = machine.ident + if i != 0: + extra = " - " + else: + extra = "" + if machine == self: + code('$extra$mid') + else: + code('$extra$mid') + code.dedent() + + code(""" +

+ + + + +""") + + for event in self.events.itervalues(): + href = "%s_Event_%s.html" % (self.ident, event.ident) + ref = self.frameRef(href, "Status", href, "1", event.short) + code('') + + code('') + # -- Body of table + for state in self.states.itervalues(): + # -- Each row + if state == active_state: + color = "yellow" + else: + color = "white" + + click = "%s_table_%s.html" % (self.ident, state.ident) + over = "%s_State_%s.html" % (self.ident, state.ident) + text = html.formatShorthand(state.short) + ref = self.frameRef(click, "Table", over, "1", state.short) + code(''' + + +''') + + # -- One column for each event + for event in self.events.itervalues(): + trans = self.table.get((state,event), None) + if trans is None: + # This is the no transition case + if state == active_state: + color = "#C0C000" + else: + color = "lightgrey" + + code('') + continue + + next = trans.nextState + stall_action = False + + # -- Get the actions + for action in trans.actions: + if action.ident == "z_stall" or \ + action.ident == "zz_recycleMandatoryQueue": + stall_action = True + + # -- Print out "actions/next-state" + if stall_action: + if state == active_state: + color = "#C0C000" + else: + color = "lightgrey" + + elif active_state and next.ident == active_state.ident: + color = "aqua" + elif state == active_state: + color = "yellow" + else: + color = "white" + + fix = code.nofix() + code('\n") + code.fix(fix) + + # -- Each row + if state == active_state: + color = "yellow" + else: + color = "white" + + click = "%s_table_%s.html" % (self.ident, state.ident) + over = "%s_State_%s.html" % (self.ident, state.ident) + ref = self.frameRef(click, "Table", over, "1", state.short) + code(''' + + +''') + code(''' + + +''') + + for event in self.events.itervalues(): + href = "%s_Event_%s.html" % (self.ident, event.ident) + ref = self.frameRef(href, "Status", href, "1", event.short) + code('') + code(''' + +
$ref
$ref ') + for action in trans.actions: + href = "%s_action_%s.html" % (self.ident, action.ident) + ref = self.frameRef(href, "Status", href, "1", + action.short) + code(' $ref\n') + if next != state: + if trans.actions: + code('/') + click = "%s_table_%s.html" % (self.ident, next.ident) + over = "%s_State_%s.html" % (self.ident, next.ident) + ref = self.frameRef(click, "Table", over, "1", next.short) + code("$ref") + code("$ref
$ref
+ +''') + + + if active_state: + name = "%s_table_%s.html" % (self.ident, active_state.ident) + else: + name = "%s_table.html" % self.ident + code.write(path, name) + +__all__ = [ "StateMachine" ] diff --git a/src/mem/slicc/symbols/Symbol.cc b/src/mem/slicc/symbols/Symbol.cc deleted file mode 100644 index 25af5ad474..0000000000 --- a/src/mem/slicc/symbols/Symbol.cc +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/slicc/symbols/Symbol.hh" - -Symbol::Symbol(string id, const Location& location, const Map& pairs) -{ - m_id = id; - m_location = location; - m_pairs = pairs; - if (!existPair("short")) { - addPair("short", m_id); - } - m_used = false; -} - -Symbol::Symbol(string id, const Location& location) -{ - m_id = id; - m_location = location; - if (!existPair("short")) { - addPair("short", m_id); - } - m_used = false; -} - -const string& Symbol::lookupPair(const string& key) const -{ - if (!existPair(key)) { - error("Value for pair '" + key + "' missing."); - } - return m_pairs.lookup(key); -} - -void Symbol::addPair(const string& key, const string& value) -{ - if (existPair(key)) { - warning("Pair key '" + key + "' re-defined. new: '" + value + "' old: '" + lookupPair(key) + "'"); - } - m_pairs.add(key, value); -} diff --git a/src/mem/slicc/symbols/Symbol.hh b/src/mem/slicc/symbols/Symbol.hh deleted file mode 100644 index 4a1c5e44ed..0000000000 --- a/src/mem/slicc/symbols/Symbol.hh +++ /dev/null @@ -1,100 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -#ifndef SYMBOL_H -#define SYMBOL_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Map.hh" -#include "mem/slicc/ast/Location.hh" - -class Symbol { -public: - // Constructors - Symbol(string id, const Location& location, const Map& pairs); - Symbol(string id, const Location& location); - // Destructor - virtual ~Symbol() { } - - // Public Methods - void error(string err_msg) const { m_location.error(err_msg); } - void warning(string err_msg) const { m_location.warning(err_msg); } - const Location& getLocation() const { return m_location; } - - const string& toString() const { return m_id; } - - const string& getIdent() const { return m_id; } - const string& getShorthand() const { return lookupPair("short"); } - const string& getDescription() const { return lookupPair("desc"); } - - void markUsed() { m_used = true; } - bool wasUsed() { return m_used; } - - bool existPair(const string& key) const { return m_pairs.exist(key); } - const string& lookupPair(const string& key) const; - void addPair(const string& key, const string& value); - - // virtual string getCode() const = 0; - virtual void writeCFiles(string path) {} - virtual void writeHTMLFiles(string path) {} - virtual void print(ostream& out) const { out << "[Symbol: " << getIdent() << "]"; } - -private: - // Private Methods - - // Private copy constructor and assignment operator - // Symbol(const Symbol& obj); - // Symbol& operator=(const Symbol& obj); - - // Data Members (m_ prefix) - string m_id; - Map m_pairs; - Location m_location; - bool m_used; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Symbol& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Symbol& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //SYMBOL_H diff --git a/src/mem/slicc/symbols/Symbol.py b/src/mem/slicc/symbols/Symbol.py new file mode 100644 index 0000000000..b394fda44a --- /dev/null +++ b/src/mem/slicc/symbols/Symbol.py @@ -0,0 +1,78 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.util import PairContainer + +class Symbol(PairContainer): + def __init__(self, symtab, ident, location, pairs=None): + super(Symbol, self).__init__() + + from slicc.util import Location + from slicc.symbols import SymbolTable + if not isinstance(symtab, SymbolTable): raise AttributeError + if not isinstance(ident, str): raise AttributeError + if not isinstance(location, Location): raise AttributeError + + self.symtab = symtab + self.ident = ident + self.location = location + if pairs: + self.pairs.update(getattr(pairs, "pairs", pairs)) + if "short" not in self: + self["short"] = self.ident + self.used = False + + def __repr__(self): + return "[Symbol: %s]" % self.ident + + def __str__(self): + return str(self.ident) + + def __setitem__(self, key, value): + if key in self.pairs: + self.warning("Pair key '%s' re-defined. new: '%s' old: '%s'", + key, value, self.pairs[key]) + super(Symbol, self).__setitem__(key, value) + + @property + def short(self): + return self["short"] + + @property + def desc(self): + return self["desc"] + + def error(self, message, *args): + self.location.error(message, *args) + + def warning(self, message, *args): + self.location.warning(message, *args) + + def writeHTMLFiles(self, path): + pass + +__all__ = [ "Symbol" ] diff --git a/src/mem/slicc/symbols/SymbolTable.cc b/src/mem/slicc/symbols/SymbolTable.cc deleted file mode 100644 index 8af3685f8c..0000000000 --- a/src/mem/slicc/symbols/SymbolTable.cc +++ /dev/null @@ -1,327 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * SymbolTable.cc - * - * Description: See SymbolTable.hh - * - * $Id$ - * - * */ - -#include "mem/slicc/symbols/SymbolTable.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/slicc/generator/html_gen.hh" -#include "mem/slicc/generator/mif_gen.hh" -#include "mem/slicc/symbols/Action.hh" - -SymbolTable g_sym_table; - -SymbolTable::SymbolTable() -{ - m_sym_map_vec.setSize(1); - m_depth = 0; - - { - Map pairs; - pairs.add("enumeration", "yes"); - newSym(new Type("MachineType", Location(), pairs)); - } - - { - Map pairs; - pairs.add("primitive", "yes"); - pairs.add("external", "yes"); - newSym(new Type("void", Location(), pairs)); - } -} - -SymbolTable::~SymbolTable() -{ - int size = m_sym_vec.size(); - for(int i=0; itoString(), sym_ptr); - m_sym_vec.insertAtBottom(sym_ptr); // Holder for the allocated Sym objects. -} - -void SymbolTable::newMachComponentSym(Symbol* sym_ptr) -{ - // used to cheat-- that is, access components in other machines - StateMachine* mach_ptr = getStateMachine("current_machine"); - if (mach_ptr != NULL) { - m_machine_component_map_vec.lookup(mach_ptr->toString()).add(sym_ptr->toString(), sym_ptr); - } -} - -Var* SymbolTable::getMachComponentVar(string mach, string ident) -{ - Symbol* s = m_machine_component_map_vec.lookup(mach).lookup(ident); - return dynamic_cast(s); -} - - -void SymbolTable::registerSym(string id, Symbol* sym_ptr) -{ - - // Check for redeclaration (in the current frame only) - if (m_sym_map_vec[m_depth].exist(id)) { - sym_ptr->error("Symbol '" + id + "' redeclared in same scope."); - } - // FIXME - warn on masking of a declaration in a previous frame - m_sym_map_vec[m_depth].add(id, sym_ptr); -} - -void SymbolTable::registerGlobalSym(string id, Symbol* sym_ptr) -{ - // Check for redeclaration (global frame only) - if (m_sym_map_vec[0].exist(id)) { - sym_ptr->error("Global symbol '" + id + "' redeclared in global scope."); - } - m_sym_map_vec[0].add(id, sym_ptr); -} - -Symbol* SymbolTable::getSym(string ident) const -{ - for (int i=m_depth; i>=0; i--) { - if (m_sym_map_vec[i].exist(ident)) { - return m_sym_map_vec[i].lookup(ident); - } - } - return NULL; -} - -void SymbolTable::newCurrentMachine(StateMachine* sym_ptr) -{ - registerGlobalSym(sym_ptr->toString(), sym_ptr); - registerSym("current_machine", sym_ptr); - m_sym_vec.insertAtBottom(sym_ptr); // Holder for the allocated Sym objects. - - Map m; - m_machine_component_map_vec.add(sym_ptr->toString(),m); - -} - -Type* SymbolTable::getType(string ident) const -{ - return dynamic_cast(getSym(ident)); -} - -Var* SymbolTable::getVar(string ident) const -{ - return dynamic_cast(getSym(ident)); -} - -Func* SymbolTable::getFunc(string ident) const -{ - return dynamic_cast(getSym(ident)); -} - -StateMachine* SymbolTable::getStateMachine(string ident) const -{ - return dynamic_cast(getSym(ident)); -} - -void SymbolTable::pushFrame() -{ - m_depth++; - m_sym_map_vec.expand(1); - m_sym_map_vec[m_depth].clear(); -} - -void SymbolTable::popFrame() -{ - m_depth--; - assert(m_depth >= 0); - m_sym_map_vec.expand(-1); -} - -void SymbolTable::writeCFiles(string path) const -{ - int size = m_sym_vec.size(); - { - // Write the Types.hh include file for the types - ostringstream sstr; - sstr << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl; - sstr << endl; - sstr << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl; - for(int i=0; i(m_sym_vec[i]); - if (type != NULL && !type->isPrimitive()) { - sstr << "#include \"mem/protocol/" << type->cIdent() << ".hh" << "\"" << endl; - } - } - conditionally_write_file(path + "/Types.hh", sstr); - } - - // Write all the symbols - for(int i=0; iwriteCFiles(path + '/'); - } - - writeControllerFactory(path); -} - -void SymbolTable::writeControllerFactory(string path) const -{ - ostringstream sstr; - int size = m_sym_vec.size(); - - sstr << "/** \\file ControllerFactory.hh " << endl; - sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl; - sstr << " */" << endl << endl; - - sstr << "#ifndef CONTROLLERFACTORY_H" << endl; - sstr << "#define CONTROLLERFACTORY_H" << endl; - sstr << endl; - - Vector< string > controller_types; - - // includes - sstr << "#include " << endl; - sstr << "class Network;" << endl; - sstr << "class AbstractController;" << endl; - sstr << endl; - - sstr << "class ControllerFactory {" << endl; - sstr << "public:" << endl; - sstr << " static AbstractController* createController(const std::string & controller_type, const std::string & name);" << endl; - sstr << "};" << endl; - sstr << endl; - - sstr << "#endif // CONTROLLERFACTORY_H" << endl; - conditionally_write_file(path + "/ControllerFactory.hh", sstr); - - // ControllerFactory.cc file - - sstr.str(""); - - sstr << "/** \\file ControllerFactory.cc " << endl; - sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl; - sstr << " */" << endl << endl; - - // includes - sstr << "#include \"mem/protocol/ControllerFactory.hh\"" << endl; - sstr << "#include \"mem/ruby/slicc_interface/AbstractController.hh\"" << endl; - sstr << "#include \"mem/protocol/MachineType.hh\"" << endl; - for(int i=0; i(m_sym_vec[i]); - if (machine != NULL) { - sstr << "#include \"mem/protocol/" << machine->getIdent() << "_Controller.hh\"" << endl; - controller_types.insertAtBottom(machine->getIdent()); - } - } - sstr << endl; - - sstr << "AbstractController* ControllerFactory::createController(const std::string & controller_type, const std::string & name) {" << endl; - for (int i=0;i SymbolTable::getStateMachines() const -{ - Vector machine_vec; - int size = m_sym_vec.size(); - for(int i=0; i(m_sym_vec[i]); - if (type != NULL) { - machine_vec.insertAtBottom(type); - } - } - return machine_vec; -} - -void SymbolTable::writeHTMLFiles(string path) const -{ - // Create index.html - { - ostringstream out; - createHTMLindex(path, out); - conditionally_write_file(path + "index.html", out); - } - - // Create empty.html - { - ostringstream out; - out << ""; - conditionally_write_file(path + "empty.html", out); - } - - // Write all the symbols - int size = m_sym_vec.size(); - for(int i=0; iwriteHTMLFiles(path); - } -} - -void write_file(string filename, ostringstream& sstr) -{ - ofstream out; - - out.open(filename.c_str()); - out << sstr.str(); - out.close(); -} - -void SymbolTable::writeMIFFiles(string path) const -{ - int size = m_sym_vec.size(); - for(int i=0; i(m_sym_vec[i]); - if (machine != NULL) { - printStateTableMIF(*machine, states); - write_file(path + machine->getIdent() + "_states.mif", states); - printEventTableMIF(*machine, events); - write_file(path + machine->getIdent() + "_events.mif", events); - printActionTableMIF(*machine, actions); - write_file(path + machine->getIdent() + "_actions.mif", actions); - printTransitionTableMIF(*machine, transitions); - write_file(path + machine->getIdent() + "_transitions.mif", transitions); - } - } -} - - -void SymbolTable::print(ostream& out) const -{ - out << "[SymbolTable]"; // FIXME -} diff --git a/src/mem/slicc/symbols/SymbolTable.hh b/src/mem/slicc/symbols/SymbolTable.hh deleted file mode 100644 index 90d3f48c3f..0000000000 --- a/src/mem/slicc/symbols/SymbolTable.hh +++ /dev/null @@ -1,121 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * SymbolTable.hh - * - * Description: - * - * $Id$ - * - * */ - -#ifndef SYMBOLTABLE_H -#define SYMBOLTABLE_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Map.hh" -#include "mem/gems_common/Vector.hh" - -#include "mem/slicc/symbols/Symbol.hh" -#include "mem/slicc/symbols/Type.hh" -#include "mem/slicc/symbols/Var.hh" -#include "mem/slicc/symbols/Func.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -class SymbolTable; - -extern SymbolTable g_sym_table; - -class SymbolTable { -public: - // Constructors - SymbolTable(); - - // Destructor - ~SymbolTable(); - - // Public Methods - void newSym(Symbol* sym_ptr); - void registerSym(string id, Symbol* sym_ptr); - Symbol* getSym(string id) const; - - // used to cheat-- that is, access components in other machines - void newMachComponentSym(Symbol* sym_ptr); - Var* getMachComponentVar(string mach, string ident); - - void newCurrentMachine(StateMachine* machine_ptr); - StateMachine* getStateMachine(string ident) const; - StateMachine* getStateMachine() const { return getStateMachine("current_machine"); } - Type* getType(string ident) const; - - Var* getVar(string ident) const; - Func* getFunc(string ident) const; - - void pushFrame(); - void popFrame(); - - Vector getStateMachines() const; - - void writeCFiles(string path) const; - void writeHTMLFiles(string path) const; - void writeMIFFiles(string path) const; - - void print(ostream& out) const; -private: - // Private Methods - void registerGlobalSym(string id, Symbol* sym_ptr); - void writeControllerFactory(string path) const; - - // Private copy constructor and assignment operator - SymbolTable(const SymbolTable& obj); - SymbolTable& operator=(const SymbolTable& obj); - - // Data Members (m_ prefix) - Vector m_sym_vec; - Vector > m_sym_map_vec; - Map > m_machine_component_map_vec; - int m_depth; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const SymbolTable& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const SymbolTable& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //SYMBOLTABLE_H diff --git a/src/mem/slicc/symbols/SymbolTable.py b/src/mem/slicc/symbols/SymbolTable.py new file mode 100644 index 0000000000..17d7dfad3d --- /dev/null +++ b/src/mem/slicc/symbols/SymbolTable.py @@ -0,0 +1,218 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter + +from slicc.generate import html +from slicc.symbols.StateMachine import StateMachine +from slicc.symbols.Type import Type +from slicc.util import Location + +class SymbolTable(object): + def __init__(self): + self.sym_vec = [] + self.sym_map_vec = [ {} ] + self.machine_components = {} + + pairs = {} + pairs["enumeration"] = "yes" + MachineType = Type(self, "MachineType", Location("init", 0), pairs) + self.newSymbol(MachineType) + + pairs = {} + pairs["primitive"] = "yes" + pairs["external"] = "yes" + void = Type(self, "void", Location("init", 0), pairs) + self.newSymbol(void) + + def __repr__(self): + return "[SymbolTable]" # FIXME + + def newSymbol(self, sym): + self.registerSym(str(sym), sym) + self.sym_vec.append(sym) + + def registerSym(self, id, sym): + # Check for redeclaration (in the current frame only) + if id in self.sym_map_vec[-1]: + sym.error("Symbol '%s' redeclared in same scope.", id) + + # FIXME - warn on masking of a declaration in a previous frame + self.sym_map_vec[-1][id] = sym + + def find(self, ident, types=None): + for sym_map in reversed(self.sym_map_vec): + try: + symbol = sym_map[ident] + except KeyError: + continue + + if types is not None: + assert isinstance(symbol, types) + + return symbol + + return None + + def newMachComponentSym(self, symbol): + # used to cheat-- that is, access components in other machines + machine = self.find("current_machine", StateMachine) + if machine: + self.machine_components[str(machine)][str(symbol)] = symbol + + def newCurrentMachine(self, sym): + self.registerGlobalSym(str(sym), sym) + self.registerSym("current_machine", sym) + self.sym_vec.append(sym) + + self.machine_components[str(sym)] = {} + + @property + def state_machine(self): + return self.find("current_machine", StateMachine) + + def pushFrame(self): + self.sym_map_vec.append({}) + + def popFrame(self): + assert len(self.sym_map_vec) > 0 + self.sym_map_vec.pop() + + def registerGlobalSym(self, ident, symbol): + # Check for redeclaration (global frame only) + if ident in self.sym_map_vec[0]: + symbol.error("Symbol '%s' redeclared in global scope." % ident) + + self.sym_map_vec[0][ident] = symbol + + def getAllType(self, type): + for symbol in self.sym_vec: + if isinstance(symbol, type): + yield symbol + + def writeCodeFiles(self, path): + code = code_formatter() + code(''' +/** Auto generated C++ code started by $__file__:$__line__ */ + +#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" +''') + for symbol in self.sym_vec: + if isinstance(symbol, Type) and not symbol.isPrimitive: + code('#include "mem/protocol/${{symbol.c_ident}}.hh"') + + code.write(path, "Types.hh") + + for symbol in self.sym_vec: + symbol.writeCodeFiles(path) + + self.writeControllerFactory(path) + + def writeControllerFactory(self, path): + code = code_formatter() + + code(''' +/** \\file ControllerFactory.hh + * Auto generatred C++ code started by $__file__:$__line__ + */ + +#ifndef CONTROLLERFACTORY_H +#define CONTROLLERFACTORY_H + +#include +class Network; +class AbstractController; + +class ControllerFactory { + public: + static AbstractController *createController(const std::string &controller_type, const std::string &name); +}; +#endif // CONTROLLERFACTORY_H''') + code.write(path, "ControllerFactory.hh") + + code = code_formatter() + code(''' +/** \\file ControllerFactory.cc + * Auto generatred C++ code started by $__file__:$__line__ + */ + +#include "mem/protocol/ControllerFactory.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/protocol/MachineType.hh" +''') + + controller_types = [] + for symbol in self.getAllType(StateMachine): + code('#include "mem/protocol/${{symbol.ident}}_Controller.hh"') + controller_types.append(symbol.ident) + + code(''' +AbstractController *ControllerFactory::createController(const std::string &controller_type, const std::string &name) { +''') + + for ct in controller_types: + code(''' + if (controller_type == "$ct") + return new ${ct}_Controller(name); +''') + + code(''' + assert(0); // invalid controller type + return NULL; +} +''') + code.write(path, "ControllerFactory.cc") + + def writeHTMLFiles(self, path): + machines = list(self.getAllType(StateMachine)) + if len(machines) > 1: + name = "%s_table.html" % machines[0].ident + else: + name = "empty.html" + + code = code_formatter() + code(''' + + +$path + + + + + + +''') + code.write(path, "index.html") + + code = code_formatter() + code("") + code.write(path, "empty.html") + + for symbol in self.sym_vec: + symbol.writeHTMLFiles(path) + +__all__ = [ "SymbolTable" ] diff --git a/src/mem/slicc/symbols/Transition.cc b/src/mem/slicc/symbols/Transition.cc deleted file mode 100644 index d6d3481663..0000000000 --- a/src/mem/slicc/symbols/Transition.cc +++ /dev/null @@ -1,173 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#include "mem/slicc/symbols/Transition.hh" -#include "mem/slicc/symbols/State.hh" -#include "mem/slicc/symbols/Event.hh" -#include "mem/slicc/symbols/Action.hh" -#include "mem/gems_common/util.hh" -#include "mem/slicc/symbols/Var.hh" - -Transition::Transition(string state, string event, string nextState, - const Vector& actionList, - const Location& location, - const Map& pairMap) - : Symbol(state + "|" + event, location, pairMap) -{ - m_state = state; - m_event = event; - m_nextState = nextState; - m_actionList = actionList; - - // Ptrs are undefined at this point - m_statePtr = NULL; - m_eventPtr = NULL; - m_nextStatePtr = NULL; - m_actionPtrsValid = false; -} - -void Transition::checkIdents(const Vector& states, - const Vector& events, - const Vector& actions) -{ - m_statePtr = findIndex(states, m_state); - m_eventPtr = findIndex(events, m_event); - m_nextStatePtr = findIndex(states, m_nextState); - - for(int i=0; i < m_actionList.size(); i++) { - Action* action_ptr = findIndex(actions, m_actionList[i]); - int size = action_ptr->getResources().keys().size(); - for (int j=0; j < size; j++) { - Var* var_ptr = action_ptr->getResources().keys()[j]; - if (var_ptr->getType()->cIdent() != "DNUCAStopTable") { - int num = atoi((action_ptr->getResources().lookup(var_ptr)).c_str()); - if (m_resources.exist(var_ptr)) { - num += atoi((m_resources.lookup(var_ptr)).c_str()); - } - m_resources.add(var_ptr, int_to_string(num)); - } else { - m_resources.add(var_ptr, action_ptr->getResources().lookup(var_ptr)); - } - } - m_actionPtrs.insertAtBottom(action_ptr); - } - m_actionPtrsValid = true; -} - -const string& Transition::getStateShorthand() const -{ - assert(m_statePtr != NULL); - return m_statePtr->getShorthand(); -} - -const string& Transition::getEventShorthand() const -{ - assert(m_eventPtr != NULL); - return m_eventPtr->getShorthand(); -} - -const string& Transition::getNextStateShorthand() const -{ - assert(m_nextStatePtr != NULL); - return m_nextStatePtr->getShorthand(); -} - -string Transition::getActionShorthands() const -{ - assert(m_actionPtrsValid); - string str; - int numActions = m_actionPtrs.size(); - for (int i=0; igetShorthand(); - } - return str; -} - -void Transition::print(ostream& out) const -{ - out << "[Transition: "; - out << "(" << m_state; - if (m_statePtr != NULL) { - out << ":" << *m_statePtr; - } - out << ", " << m_event; - if (m_eventPtr != NULL) { - out << ":" << *m_eventPtr; - } - out << ") -> "; - out << m_nextState; - if (m_nextStatePtr != NULL) { - out << ":" << *m_nextStatePtr; - } - out << ", "; - out << m_actionList; - out << "]"; -} - -Event* Transition::findIndex(const Vector& vec, string ident) -{ - int size = vec.size(); - for(int i=0; igetIdent()) { - return vec[i]; - } - } - error("Event not found: " + ident); - return NULL; -} - -State* Transition::findIndex(const Vector& vec, string ident) -{ - int size = vec.size(); - for(int i=0; igetIdent()) { - return vec[i]; - } - } - error("State not found: " + ident); - return NULL; -} - -Action* Transition::findIndex(const Vector& vec, string ident) -{ - int size = vec.size(); - for(int i=0; igetIdent()) { - return vec[i]; - } - } - error("Action not found: " + ident); - return NULL; -} - diff --git a/src/mem/slicc/symbols/Transition.hh b/src/mem/slicc/symbols/Transition.hh deleted file mode 100644 index 75d6da4e91..0000000000 --- a/src/mem/slicc/symbols/Transition.hh +++ /dev/null @@ -1,120 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Transition.hh - * - * Description: - * - * $Id$ - * - * */ - -#ifndef TRANSITION_H -#define TRANSITION_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/gems_common/Vector.hh" -#include "mem/slicc/symbols/Symbol.hh" - -class State; -class Event; -class Action; -class Var; - -class Transition : public Symbol { -public: - // Constructors - Transition(string state, string event, string nextState, - const Vector& actionList, - const Location& location, - const Map& pairMap); - // Destructor - ~Transition() { } - - // Public Methods - State* getStatePtr() const { assert(m_statePtr != NULL); return m_statePtr; } - Event* getEventPtr() const { assert(m_eventPtr != NULL); return m_eventPtr; } - State* getNextStatePtr() const { assert(m_nextStatePtr != NULL); return m_nextStatePtr; } - - // int getStateIndex() const { assert(m_statePtr != NULL); return m_statePtr->getIndex(); } - // int getEventIndex() const { assert(m_eventPtr != NULL); return m_eventPtr->getIndex(); } - // int getNextStateIndex() const { assert(m_nextStatePtr != NULL); return m_nextStatePtr->getIndex(); } - void checkIdents(const Vector& states, - const Vector& events, - const Vector& actions); - - const string& getStateShorthand() const; - const string& getEventShorthand() const; - const string& getNextStateShorthand() const; - string getActionShorthands() const; - const Vector& getActions() const { assert(m_actionPtrsValid); return m_actionPtrs; } - const Map& getResources() const { assert(m_actionPtrsValid); return m_resources; } - - void print(ostream& out) const; - - // Default copy constructor and assignment operator - // Transition(const Transition& obj); - // Transition& operator=(const Transition& obj); -private: - // Private Methods - Event* findIndex(const Vector& vec, string ident); - State* findIndex(const Vector& vec, string ident); - Action* findIndex(const Vector& vec, string ident); - - // Data Members (m_ prefix) - string m_state; - string m_event; - string m_nextState; - - State* m_statePtr; - Event* m_eventPtr; - State* m_nextStatePtr; - - Vector m_actionList; - Vector m_actionPtrs; - Map m_resources; - bool m_actionPtrsValid; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Transition& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Transition& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TRANSITION_H diff --git a/src/mem/slicc/symbols/Transition.py b/src/mem/slicc/symbols/Transition.py new file mode 100644 index 0000000000..1bf09048ab --- /dev/null +++ b/src/mem/slicc/symbols/Transition.py @@ -0,0 +1,61 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class Transition(Symbol): + def __init__(self, table, machine, state, event, nextState, actions, + location, pairs): + ident = "%s|%s" % (state, event) + super(Transition, self).__init__(table, ident, location, pairs) + + self.state = machine.states[state] + self.event = machine.events[event] + self.nextState = machine.states[nextState] + self.actions = [ machine.actions[a] for a in actions ] + self.resources = {} + + for action in self.actions: + for var,value in action.resources.iteritems(): + if var.type.ident != "DNUCAStopTable": + num = int(value) + if var in self.resources: + num += int(value) + self.resources[var] = str(num) + else: + self.resources[var] = value + + def __repr__(self): + return "[Transition: (%r, %r) -> %r, %r]" % \ + (self.state, self.event, self.nextState, self.actions) + + def getActionShorthands(self): + assert self.actions + + return ''.join(a.short for a in self.actions) + +__all__ = [ "Transition" ] diff --git a/src/mem/slicc/symbols/Type.cc b/src/mem/slicc/symbols/Type.cc deleted file mode 100644 index 5afe53423b..0000000000 --- a/src/mem/slicc/symbols/Type.cc +++ /dev/null @@ -1,779 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Type.cc - * - * Description: See Type.hh - * - * $Id$ - * */ - -#include "mem/slicc/symbols/Type.hh" -#include "mem/slicc/generator/fileio.hh" -#include "mem/gems_common/Map.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -Type::Type(string id, const Location& location, - const Map& pairs, - StateMachine* machine_ptr) - : Symbol(id, location, pairs) -{ - if (machine_ptr == NULL) { - m_c_id = id; - } else if (isExternal() || isPrimitive()) { - if (existPair("external_name")) { - m_c_id = lookupPair("external_name"); - } else { - m_c_id = id; - } - } else { - m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name - } - - if(existPair("desc")){ - m_desc = lookupPair("desc"); - } else { - m_desc = "No description avaliable"; - } - - // check for interface that this Type implements - if(existPair("interface")) { - string interface = lookupPair("interface"); - if(interface == "Message" || interface == "NetworkMessage") { - addPair("message", "yes"); - } - if(interface == "NetworkMessage") { - addPair("networkmessage", "yes"); - } - } - - // FIXME - all of the following id comparisons are fragile hacks - if ((getIdent() == "CacheMemory") || (getIdent() == "NewCacheMemory") || - (getIdent() == "TLCCacheMemory") || (getIdent() == "DNUCACacheMemory") || - (getIdent() == "DNUCABankCacheMemory") || (getIdent() == "L2BankCacheMemory") || - (getIdent() == "CompressedCacheMemory") || (getIdent() == "PrefetchCacheMemory")) { - addPair("cache", "yes"); - } - - if ((getIdent() == "TBETable") || (getIdent() == "DNUCATBETable") || (getIdent() == "DNUCAStopTable")) { - addPair("tbe", "yes"); - } - - if ((getIdent() == "NewTBETable")) { - addPair("newtbe", "yes"); - } - - if ((getIdent() == "TimerTable")) { - addPair("timer", "yes"); - } - - if ((getIdent() == "DirectoryMemory")) { - addPair("dir", "yes"); - } - - if ((getIdent() == "PersistentTable")) { - addPair("persistent", "yes"); - } - - if ((getIdent() == "Prefetcher")) { - addPair("prefetcher", "yes"); - } - - if ((getIdent() == "DNUCA_Movement")) { - addPair("mover", "yes"); - } - - if (id == "MachineType") { - m_isMachineType = true; - } else { - m_isMachineType = false; - } -} - -// Return false on error -bool Type::dataMemberAdd(string id, Type* type_ptr, Map& pairs, - string* init_code) -{ - if (dataMemberExist(id)) { - return false; // Error - } else { - m_data_member_map.add(id, type_ptr); - m_data_member_ident_vec.insertAtBottom(id); - m_data_member_type_vec.insertAtBottom(type_ptr); - m_data_member_pairs_vec.insertAtBottom(pairs); - m_data_member_init_code_vec.insertAtBottom(init_code); - } - - return true; -} - -string Type::methodId(string name, - const Vector& param_type_vec) -{ - string paramStr = ""; - for (int i = 0; i < param_type_vec.size(); i++) { - paramStr += "_"+param_type_vec[i]->cIdent(); - } - return name+paramStr; -} - -bool Type::methodAdd(string name, - Type* return_type_ptr, - const Vector& param_type_vec) -{ - string id = methodId(name, param_type_vec); - if (methodExist(id)) { - return false; // Error - } else { - m_method_return_type_map.add(id, return_type_ptr); - m_method_param_type_map.add(id, param_type_vec); - return true; - } -} - -bool Type::enumAdd(string id, Map pairs_map) -{ - if (enumExist(id)) { - return false; - } else { - m_enum_map.add(id, true); - m_enum_vec.insertAtBottom(id); - m_enum_pairs.insertAtBottom(pairs_map); - - // Add default - if (!existPair("default")) { - addPair("default", cIdent()+"_NUM"); - } - - return true; - } -} - -void Type::writeCFiles(string path) -{ - if (isExternal()) { - // Do nothing - } else if (isEnumeration()) { - printEnumH(path); - printEnumC(path); - } else { // User defined structs and messages - printTypeH(path); - printTypeC(path); - } -} - -void Type::printTypeH(string path) const -{ - ostringstream out; - int size = m_data_member_type_vec.size(); - string type_name = cIdent(); // Identifier for the type in C - - // Header - out << "/** \\file " << type_name << ".hh" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " */" << endl; - out << endl; - out << "#ifndef " << type_name << "_H" << endl; - out << "#define " << type_name << "_H" << endl; - out << endl; - - // Include all of the #includes needed - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << "#include \"mem/gems_common/Allocator.hh\"" << endl; - for (int i=0; i < size; i++) { - Type* type = m_data_member_type_vec[i]; - if (!type->isPrimitive()) { - out << "#include \"mem/protocol/" << type->cIdent() << ".hh" << "\"" << endl; - } - } - string interface = ""; - if(existPair("interface")) { - interface = lookupPair("interface"); - out << "#include \"mem/protocol/" << interface << ".hh\"" << endl; - } - - // Class definition - out << "class " << type_name; - - if(interface != "") { - out << " : public " << interface ; - } - - out << " {" << endl; - out << "public:" << endl; - - // ******** Default constructor ******** - - out << " " << type_name << "() " << endl; - - // Call superclass constructor - if (interface != "") { - out << " : " << interface << "()" << endl; - } - - out << " {" << endl; - - if(!isGlobal()) { - for (int i=0; i < size; i++) { - - Type* type_ptr = m_data_member_type_vec[i]; - string id = m_data_member_ident_vec[i]; - if (m_data_member_pairs_vec[i].exist("default")) { - // look for default value - string default_value = m_data_member_pairs_vec[i].lookup("default"); - out << " m_" << id << " = " << default_value << "; // default for this field " << endl; - } else if (type_ptr->hasDefault()) { - // Look for the type default - string default_value = type_ptr->getDefault(); - out << " m_" << id << " = " << default_value << "; // default value of " << type_ptr->cIdent() << endl; - } else { - out << " // m_" << id << " has no default" << endl; - } - } - } // end of if(!isGlobal()) - out << " }" << endl; - - // ******** Default destructor ******** - out << " "; - out << "~" << type_name << "() { };" << endl; - - // ******** Full init constructor ******** - if(! isGlobal()) { - out << " " << type_name << "("; - - for (int i=0; i < size; i++) { - if (i != 0) { - out << ", "; - } - Type* type = m_data_member_type_vec[i]; - string id = m_data_member_ident_vec[i]; - out << "const " << type->cIdent() << "& local_" << id; - } - - if (isMessage()) { - out << ", const unsigned local_proc_id" << flush; - } - - out << ")" << endl; - - // Call superclass constructor - if (interface != "") { - out << " : " << interface << "()" << endl; - } - - out << " {" << endl; - for (int i=0; i < size; i++) { - Type* type_ptr = m_data_member_type_vec[i]; - string id = m_data_member_ident_vec[i]; - out << " m_" << id << " = local_" << id << ";" << endl; - if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) { - string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack"); - out << " m_" << id << next_line_value << ";" << endl; - } - } - if (isMessage()) { - out << " proc_id = local_proc_id;" << endl << flush; - } - out << " }" << endl; - } // end of if(!isGlobal()) - - // create a static factory method - if (interface != "") { - out << " static " << interface << "* create() {" << endl; - out << " return new " << type_name << "(); " << endl; - out << " }" << endl; - } - - // bobba - - //******** Partial init constructor ******** - //** Constructor needs only the first n-1 data members for init - //** HACK to create objects with partially specified data members - //** Need to get rid of this and use hierarchy instead -// if(! isGlobal()) { -// out << " " << type_name << "("; - -// for (int i=0; i < size-1; i++) { -// if (i != 0) { -// out << ", "; -// } -// Type* type = m_data_member_type_vec[i]; -// string id = m_data_member_ident_vec[i]; -// out << "const " << type->cIdent() << "& local_" << id; -// } -// out << ")" << endl; - -// // Call superclass constructor -// if (interface != "") { -// out << " : " << interface << "()" << endl; -// } - -// out << " {" << endl; -// for (int i=0; i < size-1; i++) { -// Type* type_ptr = m_data_member_type_vec[i]; -// string id = m_data_member_ident_vec[i]; -// out << " m_" << id << " = local_" << id << ";" << endl; -// if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) { -// string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack"); -// out << " m_" << id << next_line_value << ";" << endl; -// } - -// } -// out << " }" << endl; -// } // end of if(!isGlobal()) - - // ******** Message member functions ******** - // FIXME: those should be moved into slicc file, slicc should support more of - // the c++ class inheritance - - if (isMessage()) { - out << " Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); }" << endl; - out << " void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); }" << endl; - out << " static Allocator<" << type_name << ">* s_allocator_ptr;" << endl; - out << " static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<" << type_name << ">; }}" << endl; - } - - if(!isGlobal()) { - // const Get methods for each field - out << " // Const accessors methods for each field" << endl; - for (int i=0; i < size; i++) { - Type* type_ptr = m_data_member_type_vec[i]; - string type = type_ptr->cIdent(); - string id = m_data_member_ident_vec[i]; - out << "/** \\brief Const accessor method for " << id << " field." << endl; - out << " * \\return " << id << " field" << endl; - out << " */" << endl; - out << " const " << type << "& get" << id - << "() const { return m_" << id << "; }" << endl; - } - - out << endl; - - // Non-const Get methods for each field - out << " // Non const Accessors methods for each field" << endl; - for (int i=0; i < size; i++) { - Type* type_ptr = m_data_member_type_vec[i]; - string type = type_ptr->cIdent(); - string id = m_data_member_ident_vec[i]; - out << "/** \\brief Non-const accessor method for " << id << " field." << endl; - out << " * \\return " << id << " field" << endl; - out << " */" << endl; - out << " " << type << "& get" << id - << "() { return m_" << id << "; }" << endl; - } - - out << endl; - - // Set methods for each field - out << " // Mutator methods for each field" << endl; - for (int i=0; i < size; i++) { - Type* type_ptr = m_data_member_type_vec[i]; - string type = type_ptr->cIdent(); - string id = m_data_member_ident_vec[i]; - out << "/** \\brief Mutator method for " << id << " field */" << endl; - out << " void set" << id << "(const " << type << "& local_" - << id << ") { m_" << id << " = local_" << id << "; }" << endl; - } - - out << endl; - } // end of if(!isGlobal()) - - out << " void print(ostream& out) const;" << endl; - out << "//private:" << endl; - - // Data members for each field - for (int i=0; i < size; i++) { - if (!m_data_member_pairs_vec[i].exist("abstract")) { - out << " "; - // global structure - if(isGlobal()) out << "static const "; - - Type* type = m_data_member_type_vec[i]; - string id = m_data_member_ident_vec[i]; - out << type->cIdent() << " m_" << id; - - // init value - string* init_code = m_data_member_init_code_vec[i]; - if(init_code) { - // only global structure can have init value here - assert(isGlobal()); - out << " = " << *init_code << " "; - } - out << ";"; - if (m_data_member_pairs_vec[i].exist("desc")) { - string desc = m_data_member_pairs_vec[i].lookup("desc"); - out << " /**< " << desc << "*/"; - } - out << endl; - } - } - - if (isMessage()) { - out << " unsigned proc_id;" << endl << flush; - } - - out << "};" << endl; // End class - - out << "// Output operator declaration" << endl; - out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl; - out << endl; - out << "// Output operator definition" << endl; - out << "extern inline" << endl; - out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl; - out << "{" << endl; - out << " obj.print(out);" << endl; - out << " out << flush;" << endl; - out << " return out;" << endl; - out << "}" << endl; - out << endl; - out << "#endif // " << type_name << "_H" << endl; - - // Write it out - conditionally_write_file(path + type_name + ".hh", out); -} - -void Type::printTypeC(string path) const -{ - ostringstream out; - int size = m_data_member_type_vec.size(); - string type_name = cIdent(); // Identifier for the type in C - - // Header - out << "/** \\file " << type_name << ".cc" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " */" << endl; - out << endl; - out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl; - out << endl; - if (isMessage()) { - out << "Allocator<" << type_name << ">* " << type_name << "::s_allocator_ptr = NULL;" << endl; - } - out << "/** \\brief Print the state of this object */" << endl; - out << "void " << type_name << "::print(ostream& out) const" << endl; - out << "{" << endl; - out << " out << \"[" << type_name << ": \";" << endl; - - // For each field - for (int i=0; i < size; i++) { - string id = m_data_member_ident_vec[i]; - out << " out << \"" << id << "=\" << m_" << id << " << \" \";" << endl; - } - - if (isMessage()) { - out << " out << \"" << "Time" << "=\" << getTime()" << " << \" \";" << endl; - } - - // Trailer - out << " out << \"]\";" << endl; - out << "}" << endl; - - // Write it out - conditionally_write_file(path + type_name + ".cc", out); -} - -void Type::printEnumH(string path) const -{ - ostringstream out; - int size = m_enum_vec.size(); - string type_name = cIdent(); // Identifier for the type in C - string type_desc = desc(); - - // Header - out << "/** \\file " << type_name << ".hh" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " */" << endl; - - out << "#ifndef " << type_name << "_H" << endl; - out << "#define " << type_name << "_H" << endl; - out << endl; - // Include all of the #includes needed - out << "#include \"mem/ruby/common/Global.hh\"" << endl; - out << endl; - - // Class definition - out << "/** \\enum " << type_name << endl; - out << " * \\brief " << type_desc << endl; - out << " */" << endl; - out << "enum " << type_name << " {" << endl; - - out << " " << type_name << "_FIRST," << endl; - - // For each field - for(int i = 0; i < size; i++ ) { - string id = m_enum_vec[i]; - string description; - if(m_enum_pairs[i].exist("desc")){ - description = m_enum_pairs[i].lookup("desc"); - } else { - description = "No description avaliable"; - } - if (i == 0) { - out << " " << type_name << "_" << id << " = " << type_name << "_FIRST, /**< " << description << " */" << endl; - } - else { - out << " " << type_name << "_" << id << ", /**< " << description << " */" << endl; - } - } - out << " " << type_name << "_NUM" << endl; - out << "};" << endl; - - // Code to convert from a string to the enumeration - out << type_name << " string_to_" << type_name << "(const string& str);" << endl; - - // Code to convert state to a string - out << "string " << type_name << "_to_string(const " << type_name << "& obj);" << endl; - - // Code to increment an enumeration type - out << type_name << " &operator++( " << type_name << " &e);" << endl; - - // MachineType hack used to set the base component id for each Machine - if (m_isMachineType) { - out << "int " << type_name << "_base_level(const " << type_name << "& obj);" << endl; - out << "MachineType " << type_name << "_from_base_level(int);" << endl; - out << "int " << type_name << "_base_number(const " << type_name << "& obj);" << endl; - out << "int " << type_name << "_base_count(const " << type_name << "& obj);" << endl; - // out << "int " << type_name << "_chip_count(const " << type_name << "& obj, int chipID);" << endl; - - for(int i = 0; i < size; i++ ) { - string id = m_enum_vec[i]; - out << "#define MACHINETYPE_" << id << " 1" << endl; - } - cout << endl; - } - - // Trailer - out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl; - out << endl; - out << "#endif // " << type_name << "_H" << endl; - - // Write the file - conditionally_write_file(path + type_name + ".hh", out); -} - -void Type::printEnumC(string path) const -{ - ostringstream out; - int size = m_enum_vec.size(); - string type_name = cIdent(); // Identifier for the type in C - - // Header - out << "/** \\file " << type_name << ".hh" << endl; - out << " * " << endl; - out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl; - out << " */" << endl; - - out << endl; - out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl; - if (m_isMachineType) { - out << "#include \"mem/protocol/ControllerFactory.hh\"" << endl; - for( int i = 0; i MachineNames; - for( int i = 0; i& pairs, - StateMachine* machine_ptr = NULL); - - // Destructor - ~Type() {} - - // Public Methods - string cIdent() const { return m_c_id; } - string desc() const { return m_desc; } - - bool isPrimitive() const { return existPair("primitive"); } - bool isNetworkMessage() const { return existPair("networkmessage"); } - bool isMessage() const { return existPair("message"); } - bool isBuffer() const { return existPair("buffer"); } - bool isInPort() const { return existPair("inport"); } - bool isOutPort() const { return existPair("outport"); } - bool isEnumeration() const { return existPair("enumeration"); } - bool isExternal() const { return existPair("external"); } - bool isGlobal() const { return existPair("global"); } - bool isInterface() const { return existPair("interface"); } - - // The data members of this type - only valid for messages and SLICC - // declared structures - // Return false on error - bool dataMemberAdd(string id, Type* type_ptr, Map& pairs, - string* init_code); - bool dataMemberExist(string id) const { return m_data_member_map.exist(id); } - Type* dataMemberType(string id) const { return m_data_member_map.lookup(id); } - - // The methods of this type - only valid for external types - // Return false on error - bool methodAdd(string name, Type* return_type_ptr, const Vector& param_type_vec); - bool methodExist(string id) const { return m_method_return_type_map.exist(id); } - - string methodId(string name, const Vector& param_type_vec); - Type* methodReturnType(string id) const { return m_method_return_type_map.lookup(id); } - const Vector& methodParamType(string id) const { return m_method_param_type_map.lookup(id); } - - // The enumeration idents of this type - only valid for enums - // Return false on error - bool enumAdd(string id, Map pairs); - bool enumExist(string id) const { return m_enum_map.exist(id); } - - // Write the C output files - void writeCFiles(string path) ; - - bool hasDefault() const { return existPair("default"); } - string getDefault() const { return lookupPair("default"); } - - void print(ostream& out) const {} -private: - // Private Methods - - void printTypeH(string path) const; - void printTypeC(string path) const; - void printEnumC(string path) const; - void printEnumH(string path) const; - - // Private copy constructor and assignment operator - Type(const Type& obj); - Type& operator=(const Type& obj); - - // Data Members (m_ prefix) - string m_c_id; - string m_desc; - - // Data Members - Map m_data_member_map; - Vector m_data_member_ident_vec; - Vector m_data_member_type_vec; - Vector > m_data_member_pairs_vec; - Vector m_data_member_init_code_vec; - // Needs pairs here - - // Methods - Map m_method_return_type_map; - Map > m_method_param_type_map; - // Needs pairs here - - // Enum - Map m_enum_map; - Vector m_enum_vec; - Vector< Map < string, string > > m_enum_pairs; - - // MachineType Hack - bool m_isMachineType; - -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Type& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Type& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //TYPE_H diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py new file mode 100644 index 0000000000..2541296dcb --- /dev/null +++ b/src/mem/slicc/symbols/Type.py @@ -0,0 +1,650 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.util import code_formatter, orderdict + +from slicc.util import PairContainer +from slicc.symbols.Symbol import Symbol + +class DataMember(PairContainer): + def __init__(self, ident, type, pairs, init_code): + super(DataMember, self).__init__(pairs) + self.ident = ident + self.type = type + self.init_code = init_code + +class Enumeration(PairContainer): + def __init__(self, ident, pairs): + super(Enumeration, self).__init__(pairs) + self.ident = ident + +class Method(object): + def __init__(self, return_type, param_types): + self.return_type = return_type + self.param_types = param_types + +class Type(Symbol): + def __init__(self, table, ident, location, pairs, machine=None): + super(Type, self).__init__(table, ident, location, pairs) + self.c_ident = ident + if machine: + if self.isExternal or self.isPrimitive: + if "external_name" in self: + self.c_ident = self["external_name"] + else: + # Append with machine name + self.c_ident = "%s_%s" % (machine, ident) + + self.pairs.setdefault("desc", "No description avaliable") + + # check for interface that this Type implements + if "interface" in self: + interface = self["interface"] + if interface in ("Message", "NetworkMessage"): + self["message"] = "yes" + if interface == "NetworkMessage": + self["networkmessage"] = "yes" + + # FIXME - all of the following id comparisons are fragile hacks + if self.ident in ("CacheMemory", "NewCacheMemory", + "TLCCacheMemory", "DNUCACacheMemory", + "DNUCABankCacheMemory", "L2BankCacheMemory", + "CompressedCacheMemory", "PrefetchCacheMemory"): + self["cache"] = "yes" + + if self.ident in ("TBETable", "DNUCATBETable", "DNUCAStopTable"): + self["tbe"] = "yes" + + if self.ident == "NewTBETable": + self["newtbe"] = "yes" + + if self.ident == "TimerTable": + self["timer"] = "yes" + + if self.ident == "DirectoryMemory": + self["dir"] = "yes" + + if self.ident == "PersistentTable": + self["persistent"] = "yes" + + if self.ident == "Prefetcher": + self["prefetcher"] = "yes" + + if self.ident == "DNUCA_Movement": + self["mover"] = "yes" + + self.isMachineType = (ident == "MachineType") + + self.data_members = orderdict() + + # Methods + self.methods = {} + + # Enums + self.enums = orderdict() + + @property + def isPrimitive(self): + return "primitive" in self + @property + def isNetworkMessage(self): + return "networkmessage" in self + @property + def isMessage(self): + return "message" in self + @property + def isBuffer(self): + return "buffer" in self + @property + def isInPort(self): + return "inport" in self + @property + def isOutPort(self): + return "outport" in self + @property + def isEnumeration(self): + return "enumeration" in self + @property + def isExternal(self): + return "external" in self + @property + def isGlobal(self): + return "global" in self + @property + def isInterface(self): + return "interface" in self + + # Return false on error + def dataMemberAdd(self, ident, type, pairs, init_code): + if ident in self.data_members: + return False + + member = DataMember(ident, type, pairs, init_code) + self.data_members[ident] = member + + return True + + def dataMemberType(self, ident): + return self.data_members[ident].type + + def methodId(self, name, param_type_vec): + return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ]) + + def methodAdd(self, name, return_type, param_type_vec): + ident = self.methodId(name, param_type_vec) + if ident in self.methods: + return False + + self.methods[ident] = Method(return_type, param_type_vec) + return True + + def enumAdd(self, ident, pairs): + if ident in self.enums: + return False + + self.enums[ident] = Enumeration(ident, pairs) + + # Add default + if "default" not in self: + self["default"] = "%s_NUM" % self.c_ident + + return True + + def writeCodeFiles(self, path): + if self.isExternal: + # Do nothing + pass + elif self.isEnumeration: + self.printEnumHH(path) + self.printEnumCC(path) + else: + # User defined structs and messages + self.printTypeHH(path) + self.printTypeCC(path) + + def printTypeHH(self, path): + code = code_formatter() + code(''' +/** \\file ${{self.c_ident}}.hh + * + * + * Auto generated C++ code started by $__file__:$__line__ + */ + +#ifndef ${{self.c_ident}}_H +#define ${{self.c_ident}}_H + +#include "mem/ruby/common/Global.hh" +#include "mem/gems_common/Allocator.hh" +''') + + for dm in self.data_members.values(): + if not dm.type.isPrimitive: + code('#include "mem/protocol/$0.hh"', dm.type.c_ident) + + parent = "" + if "interface" in self: + code('#include "mem/protocol/$0.hh"', self["interface"]) + parent = " : public %s" % self["interface"] + + code(''' +$klass ${{self.c_ident}}$parent { + public: + ${{self.c_ident}}() +''', klass="class") + + # Call superclass constructor + if "interface" in self: + code(' : ${{self["interface"]}}()') + + code.indent() + code("{") + if not self.isGlobal: + code.indent() + for dm in self.data_members.values(): + ident = dm.ident + if "default" in dm: + # look for default value + code('m_$ident = ${{dm["default"]}}; // default for this field') + elif "default" in dm.type: + # Look for the type default + tid = dm.type.c_ident + code('m_$ident = ${{dm.type["default"]}}; // default value of $tid') + else: + code('// m_$ident has no default') + code.dedent() + code('}') + + # ******** Default destructor ******** + code('~${{self.c_ident}}() { };') + + # ******** Full init constructor ******** + if not self.isGlobal: + params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \ + for dm in self.data_members.itervalues() ] + + if self.isMessage: + params.append('const unsigned local_proc_id') + + params = ', '.join(params) + code('${{self.c_ident}}($params)') + + # Call superclass constructor + if "interface" in self: + code(' : ${{self["interface"]}}()') + + code('{') + code.indent() + for dm in self.data_members.values(): + code('m_${{dm.ident}} = local_${{dm.ident}};') + if "nextLineCallHack" in dm: + code('m_${{dm.ident}}${{dm["nextLineCallHack"]}};') + + if self.isMessage: + code('proc_id = local_proc_id;') + + code.dedent() + code('}') + + # create a static factory method + if "interface" in self: + code(''' +static ${{self["interface"]}}* create() { + return new ${{self.c_ident}}(); +} +''') + + # ******** Message member functions ******** + # FIXME: those should be moved into slicc file, slicc should + # support more of the c++ class inheritance + + if self.isMessage: + code(''' +Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); } +void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); } +static Allocator<${{self.c_ident}}>* s_allocator_ptr; +static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<${{self.c_ident}}>; }} +''') + + if not self.isGlobal: + # const Get methods for each field + code('// Const accessors methods for each field') + for dm in self.data_members.values(): + code(''' +/** \\brief Const accessor method for ${{dm.ident}} field. + * \\return ${{dm.ident}} field + */ +const ${{dm.type.c_ident}}& get${{dm.ident}}() const { return m_${{dm.ident}}; } +''') + + # Non-const Get methods for each field + code('// Non const Accessors methods for each field') + for dm in self.data_members.values(): + code(''' +/** \\brief Non-const accessor method for ${{dm.ident}} field. + * \\return ${{dm.ident}} field + */ +${{dm.type.c_ident}}& get${{dm.ident}}() { return m_${{dm.ident}}; } +''') + + #Set methods for each field + code('// Mutator methods for each field') + for dm in self.data_members.values(): + code(''' +/** \\brief Mutator method for ${{dm.ident}} field */ +void set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) { m_${{dm.ident}} = local_${{dm.ident}}; } +''') + + code('void print(ostream& out) const;') + code.dedent() + code(' //private:') + code.indent() + + # Data members for each field + for dm in self.data_members.values(): + if "abstract" not in dm: + const = "" + init = "" + + # global structure + if self.isGlobal: + const = "static const " + + # init value + if dm.init_code: + # only global structure can have init value here + assert self.isGlobal + init = " = %s" % (dm.init_code) + + desc = "" + if "desc" in dm: + desc = '/**< %s */' % dm["desc"] + + code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init; $desc') + + if self.isMessage: + code('unsigned proc_id;') + + code.dedent() + code('};') + + code(''' +// Output operator declaration +ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj); + +// Output operator definition +extern inline +ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj) +{ + obj.print(out); + out << flush; + return out; +} + +#endif // ${{self.c_ident}}_H +''') + + code.write(path, "%s.hh" % self.c_ident) + + def printTypeCC(self, path): + code = code_formatter() + + code(''' +/** \\file ${{self.c_ident}}.cc + * + * Auto generated C++ code started by $__file__:$__line__ + */ + +#include "mem/protocol/${{self.c_ident}}.hh" +''') + + if self.isMessage: + code('Allocator<${{self.c_ident}}>* ${{self.c_ident}}::s_allocator_ptr = NULL;') + code(''' +/** \\brief Print the state of this object */ +void ${{self.c_ident}}::print(ostream& out) const +{ + out << "[${{self.c_ident}}: "; +''') + + # For each field + code.indent() + for dm in self.data_members.values(): + code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''') + + if self.isMessage: + code('out << "Time = " << getTime() << " ";') + code.dedent() + + # Trailer + code(''' + out << "]"; +}''') + + code.write(path, "%s.cc" % self.c_ident) + + def printEnumHH(self, path): + code = code_formatter() + code(''' +/** \\file ${{self.c_ident}}.hh + * + * Auto generated C++ code started by $__file__:$__line__ + */ +#ifndef ${{self.c_ident}}_H +#define ${{self.c_ident}}_H + +#include "mem/ruby/common/Global.hh" + +/** \\enum ${{self.c_ident}} + * \\brief ${{self.desc}} + */ +enum ${{self.c_ident}} { + ${{self.c_ident}}_FIRST, +''') + + code.indent() + # For each field + for i,(ident,enum) in enumerate(self.enums.iteritems()): + desc = enum.get("desc", "No description avaliable") + init = ' = %s_FIRST' % self.c_ident if i == 0 else '' + + code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */') + code.dedent() + code(''' + ${{self.c_ident}}_NUM +}; +${{self.c_ident}} string_to_${{self.c_ident}}(const string& str); +string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); +${{self.c_ident}} &operator++(${{self.c_ident}} &e); +''') + + # MachineType hack used to set the base component id for each Machine + if self.isMachineType: + code(''' +int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj); +MachineType ${{self.c_ident}}_from_base_level(int); +int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj); +int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); +''') + + for enum in self.enums.itervalues(): + code('#define MACHINETYPE_${{enum.ident}} 1') + + # Trailer + code(''' +ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj); + +#endif // ${{self.c_ident}}_H +''') + + code.write(path, "%s.hh" % self.c_ident) + + def printEnumCC(self, path): + code = code_formatter() + code(''' +/** \\file ${{self.c_ident}}.hh + * + * Auto generated C++ code started by $__file__:$__line__ + */ + +#include "mem/protocol/${{self.c_ident}}.hh" + +''') + + if self.isMachineType: + code('#include "mem/protocol/ControllerFactory.hh"') + for enum in self.enums.itervalues(): + code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') + + code(''' +ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj) +{ + out << ${{self.c_ident}}_to_string(obj); + out << flush; + return out; +} + +string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj) +{ + switch(obj) { +''') + + # For each field + code.indent() + for enum in self.enums.itervalues(): + code(' case ${{self.c_ident}}_${{enum.ident}}:') + code(' return "${{enum.ident}}";') + code.dedent() + + # Trailer + code(''' + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return ""; + } +} + +${{self.c_ident}} string_to_${{self.c_ident}}(const string& str) +{ +''') + + # For each field + code.indent() + code("if (false) {") + start = "} else " + for enum in self.enums.itervalues(): + code('${start}if (str == "${{enum.ident}}") {') + code(' return ${{self.c_ident}}_${{enum.ident}};') + code.dedent() + + code(''' + } else { + WARN_EXPR(str); + ERROR_MSG("Invalid string conversion for type ${{self.c_ident}}"); + } +} + +${{self.c_ident}}& operator++(${{self.c_ident}}& e) { + assert(e < ${{self.c_ident}}_NUM); + return e = ${{self.c_ident}}(e+1); +} +''') + + # MachineType hack used to set the base level and number of + # components for each Machine + if self.isMachineType: + code(''' +/** \\brief returns the base vector index for each machine type to be used by NetDest + * + * \\return the base vector index for each machine type to be used by NetDest + * \\see NetDest.hh + */ +int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj) +{ + switch(obj) { +''') + + # For each field + code.indent() + for i,enum in enumerate(self.enums.itervalues()): + code(' case ${{self.c_ident}}_${{enum.ident}}:') + code(' return $i;') + code.dedent() + + # total num + code(''' + case ${{self.c_ident}}_NUM: + return ${{len(self.enums)}}; + + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return -1; + } +} + +/** \\brief returns the machine type for each base vector index used by NetDest + * + * \\return the MachineTYpe + */ +MachineType ${{self.c_ident}}_from_base_level(int type) +{ + switch(type) { +''') + + # For each field + code.indent() + for i,enum in enumerate(self.enums.itervalues()): + code(' case $i:') + code(' return ${{self.c_ident}}_${{enum.ident}};') + code.dedent() + + # Trailer + code(''' + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return MachineType_NUM; + } +} + +/** \\brief The return value indicates the number of components created + * before a particular machine\'s components + * + * \\return the base number of components for each machine + */ +int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) +{ + int base = 0; + switch(obj) { +''') + + # For each field + code.indent() + code(' case ${{self.c_ident}}_NUM:') + for enum in reversed(self.enums.values()): + code(' base += ${{enum.ident}}_Controller::getNumControllers();') + code(' case ${{self.c_ident}}_${{enum.ident}}:') + code(' break;') + code.dedent() + + code(''' + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return -1; + } + + return base; +} + +/** \\brief returns the total number of components for each machine + * \\return the total number of components for each machine + */ +int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) +{ + switch(obj) { +''') + + # For each field + for enum in self.enums.itervalues(): + code(''' + case ${{self.c_ident}}_${{enum.ident}}: + return ${{enum.ident}}_Controller::getNumControllers(); +''') + + # total num + code(''' + case ${{self.c_ident}}_NUM: + default: + ERROR_MSG("Invalid range for type ${{self.c_ident}}"); + return -1; + } +} +''') + + # Write the file + code.write(path, "%s.cc" % self.c_ident) + +__all__ = [ "Type" ] diff --git a/src/mem/slicc/symbols/Var.cc b/src/mem/slicc/symbols/Var.cc deleted file mode 100644 index a6e8dfd55c..0000000000 --- a/src/mem/slicc/symbols/Var.cc +++ /dev/null @@ -1,57 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#include "mem/slicc/symbols/Var.hh" -#include "mem/slicc/symbols/StateMachine.hh" - -Var::Var(string id, const Location& location, - Type* type_ptr, string code, - const Map& pairs, - StateMachine* machine_ptr) : Symbol(id, location, pairs) -{ - if (machine_ptr == NULL) { - m_c_id = id; - } else { - m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name - } - - m_machine_ptr = machine_ptr; - m_type_ptr = type_ptr; - m_code = code; -} - -void Var::print(ostream& out) const -{ - out << "[Var id: " << m_c_id << "]" << endl; -} diff --git a/src/mem/slicc/symbols/Var.hh b/src/mem/slicc/symbols/Var.hh deleted file mode 100644 index 4cb504296a..0000000000 --- a/src/mem/slicc/symbols/Var.hh +++ /dev/null @@ -1,98 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Var.hh - * - * Description: - * - * $Id$ - * - * */ - -#ifndef VAR_H -#define VAR_H - -#include "mem/slicc/slicc_global.hh" -#include "mem/slicc/symbols/Symbol.hh" -#include "mem/slicc/symbols/Type.hh" - -class StateMachine; - -class Var : public Symbol { -public: - // Constructors - Var(string id, const Location& location, - Type* type_ptr, string code, - const Map& pairs, - StateMachine* machine_ptr = NULL); - - // Var(string id, const Location& location, - // Type* type_ptr, string code) : Symbol(id, location) { m_type_ptr = type_ptr; m_code = code; } - - // Destructor - ~Var() {} - - // Public Methods - string cIdent() const { return m_c_id; } - void writeCFiles(string path) {} - string getCode() const { return m_code; } - Type* getType() const { return m_type_ptr; } - StateMachine* getMachine() const { return m_machine_ptr; } - - void print(ostream& out) const; -private: - // Private Methods - - // Private copy constructor and assignment operator - Var(const Var& obj); - Var& operator=(const Var& obj); - - // Data Members (m_ prefix) - string m_c_id; - Type* m_type_ptr; - string m_code; - StateMachine* m_machine_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const Var& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Var& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //VAR_H diff --git a/src/mem/slicc/symbols/Var.py b/src/mem/slicc/symbols/Var.py new file mode 100644 index 0000000000..87a101f65d --- /dev/null +++ b/src/mem/slicc/symbols/Var.py @@ -0,0 +1,50 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.symbols.Symbol import Symbol + +class Var(Symbol): + def __init__(self, symtab, ident, location, type, code, pairs, + machine=None): + super(Var, self).__init__(symtab, ident, location, pairs) + + if machine: + self.c_ident = "%s_%s" % (machine, ident) + else: + self.c_ident = ident + + self.machine = machine + self.type = type + self.code = code + + def __repr__(self): + return "[Var id: %s]" % (self.c_ident) + + def writeCodeFiles(self, path): + pass + +__all__ = [ "Var" ] diff --git a/src/mem/slicc/symbols/__init__.py b/src/mem/slicc/symbols/__init__.py new file mode 100644 index 0000000000..43388a5fec --- /dev/null +++ b/src/mem/slicc/symbols/__init__.py @@ -0,0 +1,38 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Nathan Binkert + +from slicc.symbols.Action import Action +from slicc.symbols.Event import Event +from slicc.symbols.Func import Func +from slicc.symbols.State import State +from slicc.symbols.StateMachine import StateMachine +from slicc.symbols.Symbol import Symbol +from slicc.symbols.SymbolTable import SymbolTable +from slicc.symbols.Transition import Transition +from slicc.symbols.Type import Type +from slicc.symbols.Var import Var diff --git a/src/mem/slicc/util.py b/src/mem/slicc/util.py new file mode 100644 index 0000000000..abadc3e30c --- /dev/null +++ b/src/mem/slicc/util.py @@ -0,0 +1,75 @@ +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys + +def makeDir(path): + if os.path.exists(path): + if not os.path.isdir(path): + raise AttributeError, "%s exists but is not directory" % path + else: + os.mkdir(path) + +class PairContainer(object): + def __init__(self, pairs=None): + self.pairs = {} + if pairs: + self.pairs.update(pairs) + + def __contains__(self, item): + return item in self.pairs + + def __getitem__(self, item): + return self.pairs[item] + + def __setitem__(self, item, value): + self.pairs[item] = value + + def get(self, item, failobj=None): + return self.pairs.get(item, failobj) + +class Location(object): + def __init__(self, filename, lineno): + self.filename = filename + self.lineno = lineno + + def __str__(self): + return '%s:%d' % (os.path.basename(self.filename), self.lineno) + + def warning(self, message, *args): + if args: + message = message % args + #raise Exception, "%s: Warning: %s" % (self, message) + print >>sys.stderr, "%s: Warning: %s" % (self, message) + + def error(self, message, *args): + if args: + message = message % args + raise Exception, "%s: Error: %s" % (self, message) + sys.exit("\n%s: Error: %s" % (self, message)) + +__all__ = [ 'makeDir', 'PairContainer', 'Location' ] diff --git a/util/slicc b/util/slicc new file mode 100755 index 0000000000..07bd73ffaf --- /dev/null +++ b/util/slicc @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +if __name__ == "__main__": + import sys + from os.path import dirname, join + + base = dirname(__file__) + sys.path.insert(1, join(base, "../src/mem")) + sys.path.insert(1, join(base, "../src/python")) + sys.path.insert(1, join(base, "../ext/ply")) + + import slicc.main + slicc.main.main() From d9f39c8ce75aac84c88b32392c2967344362906b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 08:34:21 -0700 Subject: [PATCH 023/160] arch: nuke arch/isa_specific.hh and move stuff to generated config/the_isa.hh --- SConstruct | 11 +-- src/SConscript | 28 +++++++- src/arch/arm/stacktrace.hh | 1 + src/arch/isa_specific.hh | 70 ------------------- src/base/cp_annotate.cc | 1 + src/base/cp_annotate.hh | 1 + src/base/remote_gdb.cc | 2 +- src/cpu/base.hh | 1 + src/cpu/base_dyn_inst.hh | 1 + src/cpu/base_dyn_inst_impl.hh | 7 +- src/cpu/checker/cpu_impl.hh | 1 + src/cpu/checker/thread_context.hh | 1 + src/cpu/exetrace.cc | 1 + src/cpu/inorder/cpu.cc | 19 ++--- src/cpu/inorder/cpu.hh | 1 + src/cpu/inorder/inorder_dyn_inst.cc | 9 ++- src/cpu/inorder/inorder_dyn_inst.hh | 18 ++--- src/cpu/inorder/inorder_trace.cc | 1 + src/cpu/inorder/pipeline_stage.cc | 1 + src/cpu/inorder/reg_dep_map.cc | 1 + src/cpu/inorder/reg_dep_map.hh | 1 + src/cpu/inorder/resources/bpred_unit.cc | 1 + src/cpu/inorder/resources/branch_predictor.cc | 1 + src/cpu/inorder/resources/cache_unit.cc | 2 + src/cpu/inorder/resources/cache_unit.hh | 10 +-- src/cpu/inorder/resources/decode_unit.cc | 1 + src/cpu/inorder/resources/fetch_seq_unit.cc | 1 + src/cpu/inorder/resources/fetch_seq_unit.hh | 1 + src/cpu/inorder/resources/inst_buffer.cc | 2 + src/cpu/inorder/resources/inst_buffer_new.cc | 2 + src/cpu/inorder/resources/tlb_unit.cc | 2 + src/cpu/inorder/resources/tlb_unit.hh | 1 + src/cpu/inorder/resources/use_def.cc | 2 + src/cpu/inorder/thread_context.cc | 1 + src/cpu/inorder/thread_context.hh | 1 + src/cpu/inteltrace.cc | 1 + src/cpu/legiontrace.cc | 2 +- src/cpu/o3/bpred_unit_impl.hh | 6 +- src/cpu/o3/commit_impl.hh | 1 + src/cpu/o3/cpu.cc | 2 +- src/cpu/o3/cpu.hh | 1 + src/cpu/o3/decode_impl.hh | 1 + src/cpu/o3/dyn_inst.hh | 1 + src/cpu/o3/fetch.hh | 1 + src/cpu/o3/fetch_impl.hh | 1 + src/cpu/o3/free_list.hh | 1 + src/cpu/o3/iew_impl.hh | 1 + src/cpu/o3/impl.hh | 2 +- src/cpu/o3/lsq_unit.hh | 1 + src/cpu/o3/lsq_unit_impl.hh | 2 +- src/cpu/o3/regfile.hh | 5 +- src/cpu/o3/rename.hh | 1 + src/cpu/o3/rename_impl.hh | 1 + src/cpu/o3/rename_map.hh | 3 +- src/cpu/o3/rob.hh | 2 + src/cpu/o3/scoreboard.cc | 2 +- src/cpu/o3/thread_context.hh | 1 + src/cpu/o3/thread_context_impl.hh | 1 + src/cpu/ozone/cpu.hh | 1 + src/cpu/ozone/cpu_impl.hh | 1 + src/cpu/ozone/dyn_inst.hh | 1 + src/cpu/ozone/dyn_inst_impl.hh | 1 + src/cpu/ozone/front_end.hh | 1 + src/cpu/ozone/front_end_impl.hh | 4 +- src/cpu/ozone/inorder_back_end_impl.hh | 1 + src/cpu/ozone/lsq_unit.hh | 1 + src/cpu/ozone/lsq_unit_impl.hh | 1 + src/cpu/ozone/lw_back_end_impl.hh | 2 +- src/cpu/ozone/lw_lsq.hh | 1 + src/cpu/ozone/lw_lsq_impl.hh | 4 +- src/cpu/ozone/rename_table.hh | 1 + src/cpu/ozone/rename_table_impl.hh | 2 + src/cpu/ozone/simple_params.hh | 1 + src/cpu/ozone/thread_state.hh | 5 +- src/cpu/profile.hh | 1 + src/cpu/simple/atomic.cc | 1 + src/cpu/simple/base.cc | 1 + src/cpu/simple/base.hh | 1 + src/cpu/simple/timing.cc | 1 + src/cpu/simple_thread.cc | 1 + src/cpu/simple_thread.hh | 1 + src/cpu/static_inst.hh | 1 + src/cpu/thread_context.cc | 1 + src/cpu/thread_context.hh | 1 + src/cpu/thread_state.hh | 1 + src/dev/alpha/tsunami.cc | 1 + src/dev/alpha/tsunami_cchip.cc | 1 + src/dev/alpha/tsunami_io.cc | 1 + src/dev/alpha/tsunami_pchip.cc | 1 + src/dev/baddev.cc | 1 + src/dev/ide_disk.cc | 1 + src/dev/mips/malta.cc | 2 +- src/dev/mips/malta_cchip.cc | 3 +- src/dev/mips/malta_io.cc | 1 + src/dev/mips/malta_pchip.cc | 1 + src/dev/ns_gige.cc | 1 + src/dev/platform.cc | 1 + src/dev/sinic.cc | 1 + src/dev/sparc/dtod.cc | 1 + src/dev/sparc/t1000.cc | 1 + src/dev/uart8250.cc | 1 + src/dev/x86/pc.cc | 1 + src/kern/linux/printk.hh | 2 - src/kern/system_events.cc | 2 +- src/kern/tru64/dump_mbuf.cc | 1 + src/kern/tru64/tru64.hh | 2 + src/kern/tru64/tru64_events.cc | 1 + src/mem/cache/builder.cc | 3 +- src/mem/cache/prefetch/base.cc | 4 +- src/mem/packet_access.hh | 1 + src/mem/page_table.cc | 1 + src/mem/page_table.hh | 1 + src/mem/physical.cc | 1 + src/mem/port_impl.hh | 3 +- src/mem/rubymem.cc | 1 + src/mem/translating_port.cc | 2 + src/mem/vport.cc | 1 + src/sim/arguments.cc | 5 +- src/sim/process.cc | 2 +- src/sim/process.hh | 8 +-- src/sim/pseudo_inst.cc | 4 +- src/sim/syscall_emul.cc | 2 +- src/sim/syscall_emul.hh | 1 + src/sim/system.cc | 3 + src/sim/system.hh | 8 +-- 125 files changed, 204 insertions(+), 159 deletions(-) delete mode 100644 src/arch/isa_specific.hh diff --git a/SConstruct b/SConstruct index f143bca0e7..dac317fe8f 100644 --- a/SConstruct +++ b/SConstruct @@ -742,17 +742,10 @@ def make_switching_dir(dname, switch_headers, env): # list of ISAs from env['ALL_ISA_LIST']. def gen_switch_hdr(target, source, env): fname = str(target[0]) - bname = basename(fname) f = open(fname, 'w') - f.write('#include "arch/isa_specific.hh"\n') - cond = '#if' - for isa in all_isa_list: - f.write('%s THE_ISA == %s_ISA\n#include "%s/%s/%s"\n' - % (cond, isa.upper(), dname, isa, bname)) - cond = '#elif' - f.write('#else\n#error "THE_ISA not set"\n#endif\n') + isa = env['TARGET_ISA'].lower() + print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname)) f.close() - return 0 # String to print when generating header def gen_switch_hdr_string(target, source, env): diff --git a/src/SConscript b/src/SConscript index d3323f0a09..705d76b1dc 100644 --- a/src/SConscript +++ b/src/SConscript @@ -228,9 +228,6 @@ env.Append(CPPPATH=Dir('.')) for extra_dir in extras_dir_list: env.Append(CPPPATH=Dir(extra_dir)) -# Add a flag defining what THE_ISA should be for all compilation -env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) - # Workaround for bug in SCons version > 0.97d20071212 # Scons bug id: 2006 M5 Bug id: 308 for root, dirs, files in os.walk(base_dir, topdown=True): @@ -261,6 +258,31 @@ for extra_dir in extras_dir_list: for opt in export_vars: env.ConfigFile(opt) +def makeTheISA(source, target, env): + f = file(str(target[0]), 'w') + + isas = [ src.get_contents() for src in source ] + target = env['TARGET_ISA'] + def define(isa): + return isa.upper() + '_ISA' + + def namespace(isa): + return isa[0].upper() + isa[1:].lower() + 'ISA' + + + print >>f, '#ifndef __CONFIG_THE_ISA_HH__' + print >>f, '#define __CONFIG_THE_ISA_HH__' + print >>f + for i,isa in enumerate(isas): + print >>f, '#define %s %d' % (define(isa), i + 1) + print >>f + print >>f, '#define THE_ISA %s' % (define(target)) + print >>f, '#define TheISA %s' % (namespace(target)) + print >>f + print >>f, '#endif // __CONFIG_THE_ISA_HH__' + +env.Command('config/the_isa.hh', map(Value, all_isa_list), makeTheISA) + ######################################################################## # # Prevent any SimObjects from being added after this point, they diff --git a/src/arch/arm/stacktrace.hh b/src/arch/arm/stacktrace.hh index 3f9c910969..c5225455c5 100644 --- a/src/arch/arm/stacktrace.hh +++ b/src/arch/arm/stacktrace.hh @@ -34,6 +34,7 @@ #define __ARCH_ARM_STACKTRACE_HH__ #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/static_inst.hh" class ThreadContext; diff --git a/src/arch/isa_specific.hh b/src/arch/isa_specific.hh deleted file mode 100644 index de070bbf90..0000000000 --- a/src/arch/isa_specific.hh +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2003-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - */ - -#ifndef __ARCH_ISA_SPECIFIC_HH__ -#define __ARCH_ISA_SPECIFIC_HH__ - -//This file provides a mechanism for other source code to bring in -//files from the ISA being compiled in. - -//These are constants so you can selectively compile code based on the isa. -//To use them, do something like: -// -//#if THE_ISA == YOUR_FAVORITE_ISA -// conditional_code -//#endif -// -//Note that this is how this file sets up the TheISA macro. - -//These macros have numerical values because otherwise the preprocessor -//would treat them as 0 in comparisons. -#define ALPHA_ISA 21064 -#define SPARC_ISA 42 -#define MIPS_ISA 34000 -#define X86_ISA 8086 -#define ARM_ISA 6 - -//These tell the preprocessor where to find the files of a particular -//ISA, and set the "TheISA" macro for use elsewhere. -#if THE_ISA == ALPHA_ISA - #define TheISA AlphaISA -#elif THE_ISA == SPARC_ISA - #define TheISA SparcISA -#elif THE_ISA == MIPS_ISA - #define TheISA MipsISA -#elif THE_ISA == X86_ISA - #define TheISA X86ISA -#elif THE_ISA == ARM_ISA - #define TheISA ArmISA -#else - #error "THE_ISA not set" -#endif - -#endif diff --git a/src/base/cp_annotate.cc b/src/base/cp_annotate.cc index 0aba2d9998..4e138a6dd9 100644 --- a/src/base/cp_annotate.cc +++ b/src/base/cp_annotate.cc @@ -35,6 +35,7 @@ #include "base/loader/object_file.hh" #include "base/output.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "sim/arguments.hh" #include "sim/core.hh" diff --git a/src/base/cp_annotate.hh b/src/base/cp_annotate.hh index 05d8129d03..4248c070a6 100644 --- a/src/base/cp_annotate.hh +++ b/src/base/cp_annotate.hh @@ -41,6 +41,7 @@ #include "base/trace.hh" #include "base/types.hh" #include "config/cp_annotate.hh" +#include "config/the_isa.hh" #include "sim/serialize.hh" #include "sim/startup.hh" #include "sim/system.hh" diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 6c301b10e2..c54379c23a 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -131,9 +131,9 @@ #include "base/remote_gdb.hh" #include "base/socket.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/static_inst.hh" -//#include "mem/physical.hh" #include "mem/port.hh" #include "mem/translating_port.hh" #include "sim/system.hh" diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 441d9b5ddc..bfeec08701 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -38,6 +38,7 @@ #include "arch/microcode_rom.hh" #include "base/statistics.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "sim/eventq.hh" #include "sim/insttracer.hh" #include "mem/mem_object.hh" diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index f4ff882099..31206c81e7 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 "config/the_isa.hh" #include "cpu/o3/comm.hh" #include "cpu/exetrace.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh index 4ee7d2f2c9..70c91cedaa 100644 --- a/src/cpu/base_dyn_inst_impl.hh +++ b/src/cpu/base_dyn_inst_impl.hh @@ -35,12 +35,11 @@ #include "base/cprintf.hh" #include "base/trace.hh" - -#include "sim/faults.hh" +#include "config/the_isa.hh" +#include "cpu/base_dyn_inst.hh" #include "cpu/exetrace.hh" #include "mem/request.hh" - -#include "cpu/base_dyn_inst.hh" +#include "sim/faults.hh" #define NOHASH #ifndef NOHASH diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 26571ed688..81f4946304 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -32,6 +32,7 @@ #include #include "base/refcnt.hh" +#include "config/the_isa.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/checker/cpu.hh" #include "cpu/simple_thread.hh" diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index d38bd2915a..ef7d4c6430 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -32,6 +32,7 @@ #define __CPU_CHECKER_THREAD_CONTEXT_HH__ #include "arch/types.hh" +#include "config/the_isa.hh" #include "cpu/checker/cpu.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index ea53fb6f5c..07be700bbd 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -38,6 +38,7 @@ #include "cpu/exetrace.hh" #include "cpu/static_inst.hh" #include "cpu/thread_context.hh" +#include "config/the_isa.hh" #include "enums/OpClass.hh" using namespace std; diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 4107ac3b40..486edc87b7 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -33,21 +33,22 @@ #include "arch/utility.hh" #include "config/full_system.hh" -#include "cpu/exetrace.hh" +#include "config/the_isa.hh" #include "cpu/activity.hh" -#include "cpu/simple_thread.hh" -#include "cpu/thread_context.hh" #include "cpu/base.hh" +#include "cpu/exetrace.hh" +#include "cpu/inorder/cpu.hh" +#include "cpu/inorder/first_stage.hh" #include "cpu/inorder/inorder_dyn_inst.hh" +#include "cpu/inorder/pipeline_traits.hh" +#include "cpu/inorder/resource_pool.hh" +#include "cpu/inorder/resources/resource_list.hh" #include "cpu/inorder/thread_context.hh" #include "cpu/inorder/thread_state.hh" -#include "cpu/inorder/cpu.hh" -#include "params/InOrderCPU.hh" -#include "cpu/inorder/pipeline_traits.hh" -#include "cpu/inorder/first_stage.hh" -#include "cpu/inorder/resources/resource_list.hh" -#include "cpu/inorder/resource_pool.hh" +#include "cpu/simple_thread.hh" +#include "cpu/thread_context.hh" #include "mem/translating_port.hh" +#include "params/InOrderCPU.hh" #include "sim/process.hh" #include "sim/stat_control.hh" diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index 9fb8e0df45..3320532ba4 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -45,6 +45,7 @@ #include "base/timebuf.hh" #include "base/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/activity.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index 9f0927b2fb..5ab8396151 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -34,15 +34,14 @@ #include #include +#include "arch/faults.hh" #include "base/cprintf.hh" #include "base/trace.hh" - -#include "arch/faults.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" -#include "mem/request.hh" - -#include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/cpu.hh" +#include "cpu/inorder/inorder_dyn_inst.hh" +#include "mem/request.hh" using namespace std; using namespace TheISA; diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index a91c6a763c..522b4e8d72 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -37,28 +37,28 @@ #include #include -#include "arch/isa_traits.hh" #include "arch/faults.hh" -#include "arch/types.hh" +#include "arch/isa_traits.hh" #include "arch/mt.hh" +#include "arch/types.hh" #include "base/fast_alloc.hh" #include "base/trace.hh" #include "base/types.hh" -#include "cpu/inorder/inorder_trace.hh" #include "config/full_system.hh" -#include "cpu/thread_context.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" +#include "cpu/inorder/inorder_trace.hh" +#include "cpu/inorder/pipeline_traits.hh" +#include "cpu/inorder/resource.hh" +#include "cpu/inorder/thread_state.hh" #include "cpu/inst_seq.hh" #include "cpu/op_class.hh" #include "cpu/static_inst.hh" -#include "cpu/inorder/thread_state.hh" -#include "cpu/inorder/resource.hh" -#include "cpu/inorder/pipeline_traits.hh" +#include "cpu/thread_context.hh" #include "mem/packet.hh" #include "sim/system.hh" -#include "sim/faults.hh" -#if THE_ISA==ALPHA_ISA +#if THE_ISA == ALPHA_ISA #include "arch/alpha/ev5.hh" #endif diff --git a/src/cpu/inorder/inorder_trace.cc b/src/cpu/inorder/inorder_trace.cc index f12a1b7a95..90c94a4f56 100644 --- a/src/cpu/inorder/inorder_trace.cc +++ b/src/cpu/inorder/inorder_trace.cc @@ -31,6 +31,7 @@ #include +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/inorder/inorder_trace.hh" #include "cpu/static_inst.hh" diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index 46b1cbad0a..dc0378bf38 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -30,6 +30,7 @@ */ #include "base/str.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_stage.hh" #include "cpu/inorder/resource_pool.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/reg_dep_map.cc b/src/cpu/inorder/reg_dep_map.cc index a405b1fb9c..51782a588a 100644 --- a/src/cpu/inorder/reg_dep_map.cc +++ b/src/cpu/inorder/reg_dep_map.cc @@ -30,6 +30,7 @@ */ #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/reg_dep_map.hh" #include "cpu/inorder/inorder_dyn_inst.hh" diff --git a/src/cpu/inorder/reg_dep_map.hh b/src/cpu/inorder/reg_dep_map.hh index ba2a8c8a38..b78e211bbf 100644 --- a/src/cpu/inorder/reg_dep_map.hh +++ b/src/cpu/inorder/reg_dep_map.hh @@ -36,6 +36,7 @@ #include #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" class InOrderCPU; diff --git a/src/cpu/inorder/resources/bpred_unit.cc b/src/cpu/inorder/resources/bpred_unit.cc index 2ed8586aa3..0e8526fa13 100644 --- a/src/cpu/inorder/resources/bpred_unit.cc +++ b/src/cpu/inorder/resources/bpred_unit.cc @@ -33,6 +33,7 @@ #include "base/trace.hh" #include "base/traceflags.hh" +#include "config/the_isa.hh" #include "cpu/inorder/resources/bpred_unit.hh" using namespace std; diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc index 905de07943..ecac5fff0b 100644 --- a/src/cpu/inorder/resources/branch_predictor.cc +++ b/src/cpu/inorder/resources/branch_predictor.cc @@ -29,6 +29,7 @@ * */ +#include "config/the_isa.hh" #include "cpu/inorder/resources/branch_predictor.hh" using namespace std; diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 5677810f65..eb66e10f82 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -31,10 +31,12 @@ #include #include + #include "arch/isa_traits.hh" #include "arch/locked_mem.hh" #include "arch/utility.hh" #include "arch/predecoder.hh" +#include "config/the_isa.hh" #include "cpu/inorder/resources/cache_unit.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh index 8946ad5d38..c467e97718 100644 --- a/src/cpu/inorder/resources/cache_unit.hh +++ b/src/cpu/inorder/resources/cache_unit.hh @@ -36,17 +36,17 @@ #include #include -#include "arch/tlb.hh" #include "arch/predecoder.hh" -#include "cpu/inorder/resource.hh" +#include "arch/tlb.hh" +#include "config/the_isa.hh" #include "cpu/inorder/inorder_dyn_inst.hh" +#include "cpu/inorder/pipeline_traits.hh" +#include "cpu/inorder/resource.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" #include "mem/port.hh" -#include "cpu/inorder/pipeline_traits.hh" -#include "sim/sim_object.hh" - #include "params/InOrderCPU.hh" +#include "sim/sim_object.hh" class CacheRequest; typedef CacheRequest* CacheReqPtr; diff --git a/src/cpu/inorder/resources/decode_unit.cc b/src/cpu/inorder/resources/decode_unit.cc index 033c318f27..33f5aba1a3 100644 --- a/src/cpu/inorder/resources/decode_unit.cc +++ b/src/cpu/inorder/resources/decode_unit.cc @@ -29,6 +29,7 @@ * */ +#include "config/the_isa.hh" #include "cpu/inorder/resources/decode_unit.hh" using namespace TheISA; diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index bc809b0403..1d0b920752 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -29,6 +29,7 @@ * */ +#include "config/the_isa.hh" #include "cpu/inorder/resources/fetch_seq_unit.hh" #include "cpu/inorder/resource_pool.hh" diff --git a/src/cpu/inorder/resources/fetch_seq_unit.hh b/src/cpu/inorder/resources/fetch_seq_unit.hh index 3e18d47cb5..a4495564b6 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.hh +++ b/src/cpu/inorder/resources/fetch_seq_unit.hh @@ -36,6 +36,7 @@ #include #include +#include "config/the_isa.hh" #include "cpu/inorder/resource.hh" #include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/pipeline_traits.hh" diff --git a/src/cpu/inorder/resources/inst_buffer.cc b/src/cpu/inorder/resources/inst_buffer.cc index 21df1d053e..bb308b0ea2 100644 --- a/src/cpu/inorder/resources/inst_buffer.cc +++ b/src/cpu/inorder/resources/inst_buffer.cc @@ -31,7 +31,9 @@ #include #include + #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/resources/inst_buffer.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/resources/inst_buffer_new.cc b/src/cpu/inorder/resources/inst_buffer_new.cc index cc534ef3e5..2e5a9666a5 100644 --- a/src/cpu/inorder/resources/inst_buffer_new.cc +++ b/src/cpu/inorder/resources/inst_buffer_new.cc @@ -31,7 +31,9 @@ #include #include + #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/resources/inst_buffer.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/resources/tlb_unit.cc b/src/cpu/inorder/resources/tlb_unit.cc index 95bade36a2..0410d6b24f 100644 --- a/src/cpu/inorder/resources/tlb_unit.cc +++ b/src/cpu/inorder/resources/tlb_unit.cc @@ -31,7 +31,9 @@ #include #include + #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/first_stage.hh" #include "cpu/inorder/resources/tlb_unit.hh" diff --git a/src/cpu/inorder/resources/tlb_unit.hh b/src/cpu/inorder/resources/tlb_unit.hh index 1c08bd822a..5c62c7751f 100644 --- a/src/cpu/inorder/resources/tlb_unit.hh +++ b/src/cpu/inorder/resources/tlb_unit.hh @@ -36,6 +36,7 @@ #include #include +#include "config/the_isa.hh" #include "cpu/inorder/resources/inst_buffer.hh" #include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/pipeline_traits.hh" diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc index 2f1652c081..36392d054a 100644 --- a/src/cpu/inorder/resources/use_def.cc +++ b/src/cpu/inorder/resources/use_def.cc @@ -31,7 +31,9 @@ #include #include + #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/resources/use_def.hh" #include "cpu/inorder/cpu.hh" diff --git a/src/cpu/inorder/thread_context.cc b/src/cpu/inorder/thread_context.cc index 8247bf1fb5..41d16b633f 100644 --- a/src/cpu/inorder/thread_context.cc +++ b/src/cpu/inorder/thread_context.cc @@ -30,6 +30,7 @@ */ #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/inorder/thread_context.hh" diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh index 2489c525f1..820f3077fb 100644 --- a/src/cpu/inorder/thread_context.hh +++ b/src/cpu/inorder/thread_context.hh @@ -32,6 +32,7 @@ #ifndef __CPU_INORDER_THREAD_CONTEXT_HH__ #define __CPU_INORDER_THREAD_CONTEXT_HH__ +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/thread_context.hh" #include "cpu/inorder/thread_state.hh" diff --git a/src/cpu/inteltrace.cc b/src/cpu/inteltrace.cc index 145075dc16..ec51b80e77 100644 --- a/src/cpu/inteltrace.cc +++ b/src/cpu/inteltrace.cc @@ -33,6 +33,7 @@ #include +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/inteltrace.hh" #include "cpu/static_inst.hh" diff --git a/src/cpu/legiontrace.cc b/src/cpu/legiontrace.cc index 5face4391a..f1980c713b 100644 --- a/src/cpu/legiontrace.cc +++ b/src/cpu/legiontrace.cc @@ -31,7 +31,7 @@ * Steve Raasch */ -#include "arch/isa_specific.hh" +#include "config/the_isa.hh" #if THE_ISA != SPARC_ISA #error Legion tracing only works with SPARC simulations! #endif diff --git a/src/cpu/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh index 1378ac135b..ed34717619 100644 --- a/src/cpu/o3/bpred_unit_impl.hh +++ b/src/cpu/o3/bpred_unit_impl.hh @@ -28,16 +28,16 @@ * Authors: Kevin Lim */ +#include + #include "arch/types.hh" #include "arch/isa_traits.hh" #include "base/trace.hh" #include "base/traceflags.hh" +#include "config/the_isa.hh" #include "cpu/o3/bpred_unit.hh" - #include "params/DerivO3CPU.hh" -#include - template BPredUnit::BPredUnit(DerivO3CPUParams *params) : _name(params->name + ".BPredUnit"), diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 7286f1b6fd..aa0f792726 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -37,6 +37,7 @@ #include "base/loader/symtab.hh" #include "base/timebuf.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" #include "cpu/exetrace.hh" #include "cpu/o3/commit.hh" diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 6722941e4b..de1e242019 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -30,8 +30,8 @@ */ #include "config/full_system.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" - #include "cpu/activity.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 0cc8eab785..65170d8b2f 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -42,6 +42,7 @@ #include "base/statistics.hh" #include "base/timebuf.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" #include "cpu/activity.hh" #include "cpu/base.hh" diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh index 86f87991c4..1b76de1320 100644 --- a/src/cpu/o3/decode_impl.hh +++ b/src/cpu/o3/decode_impl.hh @@ -28,6 +28,7 @@ * Authors: Kevin Lim */ +#include "config/the_isa.hh" #include "cpu/o3/decode.hh" #include "params/DerivO3CPU.hh" diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index 3ef42e91f3..e1279f82b5 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -32,6 +32,7 @@ #define __CPU_O3_DYN_INST_HH__ #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/inst_seq.hh" #include "cpu/o3/cpu.hh" diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 9cbc508995..425c34428e 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -36,6 +36,7 @@ #include "arch/predecoder.hh" #include "base/statistics.hh" #include "base/timebuf.hh" +#include "config/the_isa.hh" #include "cpu/pc_event.hh" #include "mem/packet.hh" #include "mem/port.hh" diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 3781113bdb..5c6e287dcb 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -35,6 +35,7 @@ #include "arch/isa_traits.hh" #include "arch/utility.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" #include "cpu/checker/cpu.hh" #include "cpu/exetrace.hh" diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh index e28c4910e0..96289f6419 100644 --- a/src/cpu/o3/free_list.hh +++ b/src/cpu/o3/free_list.hh @@ -38,6 +38,7 @@ #include "base/misc.hh" #include "base/trace.hh" #include "base/traceflags.hh" +#include "config/the_isa.hh" #include "cpu/o3/comm.hh" /** diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index ba29df1965..751a26afd8 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -35,6 +35,7 @@ #include #include "base/timebuf.hh" +#include "config/the_isa.hh" #include "cpu/o3/fu_pool.hh" #include "cpu/o3/iew.hh" #include "params/DerivO3CPU.hh" diff --git a/src/cpu/o3/impl.hh b/src/cpu/o3/impl.hh index 4b29b4daa4..ffccd4a84b 100644 --- a/src/cpu/o3/impl.hh +++ b/src/cpu/o3/impl.hh @@ -32,7 +32,7 @@ #define __CPU_O3_IMPL_HH__ #include "arch/isa_traits.hh" - +#include "config/the_isa.hh" #include "cpu/o3/cpu_policy.hh" diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index a917caef36..6ff36d9293 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -40,6 +40,7 @@ #include "arch/faults.hh" #include "arch/locked_mem.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "base/fast_alloc.hh" #include "base/hashmap.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index edc8c9b3f5..9ee1de45ae 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -30,8 +30,8 @@ */ #include "arch/locked_mem.hh" +#include "config/the_isa.hh" #include "config/use_checker.hh" - #include "cpu/o3/lsq.hh" #include "cpu/o3/lsq_unit.hh" #include "base/str.hh" diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index d6beecdc50..e252fa362b 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -32,18 +32,19 @@ #ifndef __CPU_O3_REGFILE_HH__ #define __CPU_O3_REGFILE_HH__ +#include + #include "arch/isa_traits.hh" #include "arch/types.hh" #include "base/trace.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/o3/comm.hh" #if FULL_SYSTEM #include "arch/kernel_stats.hh" #endif -#include - /** * Simple physical register file class. * Right now this is specific to Alpha until we decide if/how to make things diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index 734b63105a..8c21dda0a2 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -35,6 +35,7 @@ #include "base/statistics.hh" #include "base/timebuf.hh" +#include "config/the_isa.hh" class DerivO3CPUParams; diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index e4cc2674b9..ce206435c0 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -34,6 +34,7 @@ #include "arch/isa_traits.hh" #include "arch/registers.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/o3/rename.hh" #include "params/DerivO3CPU.hh" diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh index 896c66f3e1..51d8db4d81 100644 --- a/src/cpu/o3/rename_map.hh +++ b/src/cpu/o3/rename_map.hh @@ -39,8 +39,9 @@ #include #include -#include "cpu/o3/free_list.hh" #include "arch/types.hh" +#include "config/the_isa.hh" +#include "cpu/o3/free_list.hh" class SimpleRenameMap { diff --git a/src/cpu/o3/rob.hh b/src/cpu/o3/rob.hh index 657bc8d067..bdea07d1a4 100644 --- a/src/cpu/o3/rob.hh +++ b/src/cpu/o3/rob.hh @@ -36,6 +36,8 @@ #include #include +#include "config/the_isa.hh" + /** * ROB class. The ROB is largely what drives squashing. */ diff --git a/src/cpu/o3/scoreboard.cc b/src/cpu/o3/scoreboard.cc index e7f8b7949f..ae1e13717c 100644 --- a/src/cpu/o3/scoreboard.cc +++ b/src/cpu/o3/scoreboard.cc @@ -29,7 +29,7 @@ * Kevin Lim */ -#include "arch/isa_specific.hh" +#include "config/the_isa.hh" #include "cpu/o3/scoreboard.hh" Scoreboard::Scoreboard(unsigned activeThreads, diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index ed5c6ac200..695b3b91a6 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -31,6 +31,7 @@ #ifndef __CPU_O3_THREAD_CONTEXT_HH__ #define __CPU_O3_THREAD_CONTEXT_HH__ +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/o3/isa_specific.hh" diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index e631c9244e..940d460ced 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -30,6 +30,7 @@ */ #include "arch/registers.hh" +#include "config/the_isa.hh" #include "cpu/o3/thread_context.hh" #include "cpu/quiesce_event.hh" diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index 5e36332afb..a16986c997 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -36,6 +36,7 @@ #include "base/statistics.hh" #include "base/timebuf.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh index f86b882d1b..c09dd9046f 100644 --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@ -34,6 +34,7 @@ #include "arch/isa_traits.hh" // For MachInst #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh index a39f383ba9..cca72ef18f 100644 --- a/src/cpu/ozone/dyn_inst.hh +++ b/src/cpu/ozone/dyn_inst.hh @@ -34,6 +34,7 @@ #include "arch/isa_traits.hh" #include "arch/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/inst_seq.hh" #include "cpu/ozone/cpu.hh" // MUST include this diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh index 8519917f5a..bfefb9428c 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -30,6 +30,7 @@ #include "sim/faults.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/ozone/dyn_inst.hh" #if FULL_SYSTEM diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh index 38fc89e3fe..3809db00db 100644 --- a/src/cpu/ozone/front_end.hh +++ b/src/cpu/ozone/front_end.hh @@ -35,6 +35,7 @@ #include "arch/utility.hh" #include "base/timebuf.hh" +#include "config/the_isa.hh" #include "cpu/inst_seq.hh" #include "cpu/o3/bpred_unit.hh" #include "cpu/ozone/rename_table.hh" diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 516823b471..8841369276 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -28,12 +28,12 @@ * Authors: Kevin Lim */ -#include "config/use_checker.hh" - #include "sim/faults.hh" #include "arch/isa_traits.hh" #include "arch/utility.hh" #include "base/statistics.hh" +#include "config/the_isa.hh" +#include "config/use_checker.hh" #include "cpu/thread_context.hh" #include "cpu/exetrace.hh" #include "cpu/ozone/front_end.hh" diff --git a/src/cpu/ozone/inorder_back_end_impl.hh b/src/cpu/ozone/inorder_back_end_impl.hh index 798b628d65..2d4d225c74 100644 --- a/src/cpu/ozone/inorder_back_end_impl.hh +++ b/src/cpu/ozone/inorder_back_end_impl.hh @@ -30,6 +30,7 @@ #include "sim/faults.hh" #include "arch/types.hh" +#include "config/the_isa.hh" #include "cpu/ozone/inorder_back_end.hh" #include "cpu/ozone/thread_state.hh" diff --git a/src/cpu/ozone/lsq_unit.hh b/src/cpu/ozone/lsq_unit.hh index 47be245e5e..d8e402b652 100644 --- a/src/cpu/ozone/lsq_unit.hh +++ b/src/cpu/ozone/lsq_unit.hh @@ -38,6 +38,7 @@ #include "arch/faults.hh" #include "arch/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "base/hashmap.hh" #include "cpu/inst_seq.hh" #include "mem/mem_interface.hh" diff --git a/src/cpu/ozone/lsq_unit_impl.hh b/src/cpu/ozone/lsq_unit_impl.hh index 833aa05812..dd44adf6ed 100644 --- a/src/cpu/ozone/lsq_unit_impl.hh +++ b/src/cpu/ozone/lsq_unit_impl.hh @@ -30,6 +30,7 @@ #include "arch/faults.hh" #include "base/str.hh" +#include "config/the_isa.hh" #include "cpu/ozone/lsq_unit.hh" template diff --git a/src/cpu/ozone/lw_back_end_impl.hh b/src/cpu/ozone/lw_back_end_impl.hh index 86d4531a0a..cbc386cb0f 100644 --- a/src/cpu/ozone/lw_back_end_impl.hh +++ b/src/cpu/ozone/lw_back_end_impl.hh @@ -28,8 +28,8 @@ * Authors: Kevin Lim */ +#include "config/the_isa.hh" #include "config/use_checker.hh" - #include "cpu/ozone/lw_back_end.hh" #include "cpu/op_class.hh" diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh index 6e9bb77af5..ee03129694 100644 --- a/src/cpu/ozone/lw_lsq.hh +++ b/src/cpu/ozone/lw_lsq.hh @@ -39,6 +39,7 @@ #include "arch/faults.hh" #include "arch/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "base/fast_alloc.hh" #include "base/hashmap.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh index 4d290a1e99..c714c5d382 100644 --- a/src/cpu/ozone/lw_lsq_impl.hh +++ b/src/cpu/ozone/lw_lsq_impl.hh @@ -28,10 +28,10 @@ * Authors: Kevin Lim */ -#include "config/use_checker.hh" - #include "arch/faults.hh" #include "base/str.hh" +#include "config/the_isa.hh" +#include "config/use_checker.hh" #include "cpu/ozone/lw_lsq.hh" #include "cpu/checker/cpu.hh" diff --git a/src/cpu/ozone/rename_table.hh b/src/cpu/ozone/rename_table.hh index 0b67d9635c..9a5579158b 100644 --- a/src/cpu/ozone/rename_table.hh +++ b/src/cpu/ozone/rename_table.hh @@ -32,6 +32,7 @@ #define __CPU_OZONE_RENAME_TABLE_HH__ #include "arch/isa_traits.hh" +#include "config/the_isa.hh" /** Rename table that holds the rename of each architectural register to * producing DynInst. Needs to support copying from one table to another. diff --git a/src/cpu/ozone/rename_table_impl.hh b/src/cpu/ozone/rename_table_impl.hh index 67bab73373..e8071e2b3c 100644 --- a/src/cpu/ozone/rename_table_impl.hh +++ b/src/cpu/ozone/rename_table_impl.hh @@ -29,6 +29,8 @@ */ #include // Not really sure what to include to get NULL + +#include "config/the_isa.hh" #include "cpu/ozone/rename_table.hh" template diff --git a/src/cpu/ozone/simple_params.hh b/src/cpu/ozone/simple_params.hh index 7687fdf60c..b241dea73b 100644 --- a/src/cpu/ozone/simple_params.hh +++ b/src/cpu/ozone/simple_params.hh @@ -31,6 +31,7 @@ #ifndef __CPU_OZONE_SIMPLE_PARAMS_HH__ #define __CPU_OZONE_SIMPLE_PARAMS_HH__ +#include "config/the_isa.hh" #include "cpu/ozone/cpu.hh" //Forward declarations diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh index 971fba8860..638b9d86c2 100644 --- a/src/cpu/ozone/thread_state.hh +++ b/src/cpu/ozone/thread_state.hh @@ -31,13 +31,14 @@ #ifndef __CPU_OZONE_THREAD_STATE_HH__ #define __CPU_OZONE_THREAD_STATE_HH__ -#include "sim/faults.hh" -#include "arch/types.hh" #include "arch/regfile.hh" +#include "arch/types.hh" #include "base/callback.hh" #include "base/output.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" +#include "sim/faults.hh" #include "sim/process.hh" #include "sim/sim_exit.hh" diff --git a/src/cpu/profile.hh b/src/cpu/profile.hh index 9606ed24d9..dd856b5a79 100644 --- a/src/cpu/profile.hh +++ b/src/cpu/profile.hh @@ -34,6 +34,7 @@ #include #include "arch/stacktrace.hh" +#include "config/the_isa.hh" #include "cpu/static_inst.hh" #include "base/types.hh" diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 83da618f8e..cd4f5457eb 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -32,6 +32,7 @@ #include "arch/mmaped_ipr.hh" #include "arch/utility.hh" #include "base/bigint.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/simple/atomic.hh" #include "mem/packet.hh" diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 732bb637b8..0104e1b1fe 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -40,6 +40,7 @@ #include "base/stats/events.hh" #include "base/trace.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" #include "cpu/profile.hh" diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 466d0d1c9d..39961fb881 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -36,6 +36,7 @@ #include "arch/predecoder.hh" #include "base/statistics.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/pc_event.hh" diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 672fd94147..8d3bae3f69 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -32,6 +32,7 @@ #include "arch/mmaped_ipr.hh" #include "arch/utility.hh" #include "base/bigint.hh" +#include "config/the_isa.hh" #include "cpu/exetrace.hh" #include "cpu/simple/timing.hh" #include "mem/packet.hh" diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 22bc283a3e..92c6ad69b5 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -34,6 +34,7 @@ #include #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 8a44eba371..2d28607b46 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -39,6 +39,7 @@ #include "arch/types.hh" #include "base/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" #include "mem/request.hh" diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index b1298e0e9e..fdec097560 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -36,6 +36,7 @@ #include "arch/isa_traits.hh" #include "arch/utility.hh" +#include "config/the_isa.hh" #include "base/bitfield.hh" #include "base/hashmap.hh" #include "base/misc.hh" diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc index ab105a4350..f2083ef081 100644 --- a/src/cpu/thread_context.cc +++ b/src/cpu/thread_context.cc @@ -30,6 +30,7 @@ #include "base/misc.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" void diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 9e34204ef4..78ecdacf2d 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -35,6 +35,7 @@ #include "arch/types.hh" #include "base/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "mem/request.hh" #include "sim/byteswap.hh" #include "sim/faults.hh" diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 5c7c0ea56c..cf637aedaf 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -32,6 +32,7 @@ #define __CPU_THREAD_STATE_HH__ #include "arch/types.hh" +#include "config/the_isa.hh" #include "cpu/profile.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" diff --git a/src/dev/alpha/tsunami.cc b/src/dev/alpha/tsunami.cc index b6478fe225..b36b5977df 100644 --- a/src/dev/alpha/tsunami.cc +++ b/src/dev/alpha/tsunami.cc @@ -36,6 +36,7 @@ #include #include +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "dev/alpha/tsunami_cchip.hh" #include "dev/alpha/tsunami_pchip.hh" diff --git a/src/dev/alpha/tsunami_cchip.cc b/src/dev/alpha/tsunami_cchip.cc index 52a2aea14c..fd76fd93e8 100644 --- a/src/dev/alpha/tsunami_cchip.cc +++ b/src/dev/alpha/tsunami_cchip.cc @@ -39,6 +39,7 @@ #include "arch/alpha/ev5.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "cpu/thread_context.hh" #include "dev/alpha/tsunami.hh" diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc index 9c88904e32..8b06f51702 100644 --- a/src/dev/alpha/tsunami_io.cc +++ b/src/dev/alpha/tsunami_io.cc @@ -42,6 +42,7 @@ #include "base/time.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/rtcreg.h" #include "dev/alpha/tsunami_cchip.hh" #include "dev/alpha/tsunami.hh" diff --git a/src/dev/alpha/tsunami_pchip.cc b/src/dev/alpha/tsunami_pchip.cc index 4df7d11500..df980cf797 100644 --- a/src/dev/alpha/tsunami_pchip.cc +++ b/src/dev/alpha/tsunami_pchip.cc @@ -38,6 +38,7 @@ #include #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/alpha/tsunami_pchip.hh" #include "dev/alpha/tsunamireg.h" #include "dev/alpha/tsunami.hh" diff --git a/src/dev/baddev.cc b/src/dev/baddev.cc index 6cdee03102..356574c718 100644 --- a/src/dev/baddev.cc +++ b/src/dev/baddev.cc @@ -37,6 +37,7 @@ #include #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/baddev.hh" #include "dev/platform.hh" #include "mem/port.hh" diff --git a/src/dev/ide_disk.cc b/src/dev/ide_disk.cc index 83faf508ee..fe93924f97 100644 --- a/src/dev/ide_disk.cc +++ b/src/dev/ide_disk.cc @@ -39,6 +39,7 @@ #include #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "base/chunk_generator.hh" #include "base/cprintf.hh" // csprintf #include "base/trace.hh" diff --git a/src/dev/mips/malta.cc b/src/dev/mips/malta.cc index 1401fe9ee8..73dc9f1162 100755 --- a/src/dev/mips/malta.cc +++ b/src/dev/mips/malta.cc @@ -37,6 +37,7 @@ #include #include +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "dev/mips/malta_cchip.hh" #include "dev/mips/malta_pchip.hh" @@ -46,7 +47,6 @@ #include "params/Malta.hh" #include "sim/system.hh" - using namespace std; using namespace TheISA; diff --git a/src/dev/mips/malta_cchip.cc b/src/dev/mips/malta_cchip.cc index 2659776652..b2d5069c52 100755 --- a/src/dev/mips/malta_cchip.cc +++ b/src/dev/mips/malta_cchip.cc @@ -39,6 +39,7 @@ #include "arch/mips/mips_core_specific.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "cpu/thread_context.hh" #include "dev/mips/malta.hh" @@ -56,7 +57,7 @@ using namespace TheISA; MaltaCChip::MaltaCChip(Params *p) : BasicPioDevice(p), malta(p->malta) { - warn("MaltaCCHIP::MaltaCChip() not implemented."); + warn("MaltaCCHIP::MaltaCChip() not implemented."); pioSize = 0xfffffff; //Put back pointer in malta diff --git a/src/dev/mips/malta_io.cc b/src/dev/mips/malta_io.cc index 7f04789dbc..5a738a9b45 100755 --- a/src/dev/mips/malta_io.cc +++ b/src/dev/mips/malta_io.cc @@ -42,6 +42,7 @@ #include "base/time.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/rtcreg.h" #include "dev/mips/malta_cchip.hh" #include "dev/mips/malta.hh" diff --git a/src/dev/mips/malta_pchip.cc b/src/dev/mips/malta_pchip.cc index b357e3b61c..0354330218 100755 --- a/src/dev/mips/malta_pchip.cc +++ b/src/dev/mips/malta_pchip.cc @@ -38,6 +38,7 @@ #include #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/mips/malta_pchip.hh" #include "dev/mips/maltareg.h" #include "dev/mips/malta.hh" diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc index 912ca7f0fd..86f081ec58 100644 --- a/src/dev/ns_gige.cc +++ b/src/dev/ns_gige.cc @@ -39,6 +39,7 @@ #include "base/debug.hh" #include "base/inet.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "dev/etherlink.hh" #include "dev/ns_gige.hh" diff --git a/src/dev/platform.cc b/src/dev/platform.cc index 2b51a6245b..a91a5abf96 100644 --- a/src/dev/platform.cc +++ b/src/dev/platform.cc @@ -30,6 +30,7 @@ */ #include "base/misc.hh" +#include "config/the_isa.hh" #include "dev/platform.hh" #include "sim/sim_exit.hh" diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc index 133f70b0bf..86090e0483 100644 --- a/src/dev/sinic.cc +++ b/src/dev/sinic.cc @@ -36,6 +36,7 @@ #include "base/debug.hh" #include "base/inet.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "cpu/thread_context.hh" #include "dev/etherlink.hh" diff --git a/src/dev/sparc/dtod.cc b/src/dev/sparc/dtod.cc index 81132ac659..c7243cfb87 100644 --- a/src/dev/sparc/dtod.cc +++ b/src/dev/sparc/dtod.cc @@ -39,6 +39,7 @@ #include "base/time.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/sparc/dtod.hh" #include "dev/platform.hh" #include "mem/packet_access.hh" diff --git a/src/dev/sparc/t1000.cc b/src/dev/sparc/t1000.cc index 88fb358efc..c00d942c94 100644 --- a/src/dev/sparc/t1000.cc +++ b/src/dev/sparc/t1000.cc @@ -36,6 +36,7 @@ #include #include +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "dev/sparc/t1000.hh" #include "dev/terminal.hh" diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc index 93f71f49b4..e3eacaaa20 100644 --- a/src/dev/uart8250.cc +++ b/src/dev/uart8250.cc @@ -38,6 +38,7 @@ #include "base/inifile.hh" #include "base/str.hh" // for to_number #include "base/trace.hh" +#include "config/the_isa.hh" #include "dev/platform.hh" #include "dev/terminal.hh" #include "dev/uart8250.hh" diff --git a/src/dev/x86/pc.cc b/src/dev/x86/pc.cc index 7dc1d87115..e3449abf60 100644 --- a/src/dev/x86/pc.cc +++ b/src/dev/x86/pc.cc @@ -38,6 +38,7 @@ #include "arch/x86/intmessage.hh" #include "arch/x86/x86_traits.hh" +#include "config/the_isa.hh" #include "cpu/intr_control.hh" #include "dev/terminal.hh" #include "dev/x86/i82094aa.hh" diff --git a/src/kern/linux/printk.hh b/src/kern/linux/printk.hh index da9564b7e9..5c6ee073d5 100644 --- a/src/kern/linux/printk.hh +++ b/src/kern/linux/printk.hh @@ -32,8 +32,6 @@ #ifndef __PRINTK_HH__ #define __PRINTK_HH__ -#include "arch/isa_specific.hh" - #include class Arguments; diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc index 6fd9e15636..bd01ed9ede 100644 --- a/src/kern/system_events.cc +++ b/src/kern/system_events.cc @@ -29,9 +29,9 @@ * Nathan Binkert */ -//For ISA_HAS_DELAY_SLOT #include "arch/isa_traits.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "kern/system_events.hh" diff --git a/src/kern/tru64/dump_mbuf.cc b/src/kern/tru64/dump_mbuf.cc index 517aad6fa9..207d307920 100644 --- a/src/kern/tru64/dump_mbuf.cc +++ b/src/kern/tru64/dump_mbuf.cc @@ -37,6 +37,7 @@ #include "base/loader/symtab.hh" #include "base/trace.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "kern/tru64/mbuf.hh" #include "sim/arguments.hh" diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh index bf46e0de47..c2bdd27764 100644 --- a/src/kern/tru64/tru64.hh +++ b/src/kern/tru64/tru64.hh @@ -31,6 +31,7 @@ #ifndef __TRU64_HH__ #define __TRU64_HH__ + #include "config/full_system.hh" #include "kern/operatingsystem.hh" @@ -55,6 +56,7 @@ class Tru64 {}; #include // for memset() #include +#include "config/the_isa.hh" #include "arch/alpha/registers.hh" #include "cpu/base.hh" #include "sim/core.hh" diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc index 4867df5592..460f75dea9 100644 --- a/src/kern/tru64/tru64_events.cc +++ b/src/kern/tru64/tru64_events.cc @@ -31,6 +31,7 @@ #include "arch/alpha/ev5.hh" #include "arch/isa_traits.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "kern/system_events.hh" diff --git a/src/mem/cache/builder.cc b/src/mem/cache/builder.cc index 599353b885..bd9eb9accc 100644 --- a/src/mem/cache/builder.cc +++ b/src/mem/cache/builder.cc @@ -33,9 +33,10 @@ * @file * Simobject instatiation of caches. */ +#include #include -// Must be included first to determine which caches we want +#include "config/the_isa.hh" #include "enums/Prefetch.hh" #include "mem/config/cache.hh" #include "mem/cache/base.hh" diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc index f20a306cbe..f0e244a09b 100644 --- a/src/mem/cache/prefetch/base.cc +++ b/src/mem/cache/prefetch/base.cc @@ -33,12 +33,14 @@ * Hardware Prefetcher Definition. */ +#include + #include "arch/isa_traits.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "mem/cache/base.hh" #include "mem/cache/prefetch/base.hh" #include "mem/request.hh" -#include BasePrefetcher::BasePrefetcher(const BaseCacheParams *p) : size(p->prefetcher_size), pageStop(!p->prefetch_past_page), diff --git a/src/mem/packet_access.hh b/src/mem/packet_access.hh index f70d508b21..fca9606fc8 100644 --- a/src/mem/packet_access.hh +++ b/src/mem/packet_access.hh @@ -31,6 +31,7 @@ #include "arch/isa_traits.hh" #include "base/bigint.hh" +#include "config/the_isa.hh" #include "mem/packet.hh" #include "sim/byteswap.hh" diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index bf35932a66..4bc3a4434d 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -42,6 +42,7 @@ #include "base/bitfield.hh" #include "base/intmath.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "mem/page_table.hh" #include "sim/process.hh" #include "sim/sim_object.hh" diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index 3ce720ad48..0d93d37c78 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -42,6 +42,7 @@ #include "arch/tlb.hh" #include "base/hashmap.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "mem/request.hh" #include "sim/faults.hh" #include "sim/serialize.hh" diff --git a/src/mem/physical.cc b/src/mem/physical.cc index d87ad3b220..be4086cd90 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -44,6 +44,7 @@ #include "base/random.hh" #include "base/types.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "mem/packet_access.hh" #include "mem/physical.hh" #include "sim/eventq.hh" diff --git a/src/mem/port_impl.hh b/src/mem/port_impl.hh index 989cfd3383..bc95921647 100644 --- a/src/mem/port_impl.hh +++ b/src/mem/port_impl.hh @@ -28,9 +28,8 @@ * Authors: Ali Saidi */ -//To get endianness #include "arch/isa_traits.hh" - +#include "config/the_isa.hh" #include "mem/port.hh" #include "sim/byteswap.hh" diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index 4d9f8051f6..2fb529e12d 100644 --- a/src/mem/rubymem.cc +++ b/src/mem/rubymem.cc @@ -35,6 +35,7 @@ #include "base/output.hh" #include "base/str.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "mem/ruby/common/Debug.hh" #include "mem/ruby/libruby.hh" #include "mem/ruby/system/RubyPort.hh" diff --git a/src/mem/translating_port.cc b/src/mem/translating_port.cc index 54de6625e0..700229b23f 100644 --- a/src/mem/translating_port.cc +++ b/src/mem/translating_port.cc @@ -30,7 +30,9 @@ */ #include + #include "base/chunk_generator.hh" +#include "config/the_isa.hh" #include "mem/port.hh" #include "mem/translating_port.hh" #include "mem/page_table.hh" diff --git a/src/mem/vport.cc b/src/mem/vport.cc index 15be45c2a4..ab061c0192 100644 --- a/src/mem/vport.cc +++ b/src/mem/vport.cc @@ -34,6 +34,7 @@ */ #include "base/chunk_generator.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "mem/vport.hh" diff --git a/src/sim/arguments.cc b/src/sim/arguments.cc index 5aa57755a8..339a57f909 100644 --- a/src/sim/arguments.cc +++ b/src/sim/arguments.cc @@ -28,11 +28,10 @@ * Authors: Nathan Binkert */ -#include "sim/arguments.hh" #include "arch/utility.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" - -using namespace TheISA; +#include "sim/arguments.hh" Arguments::Data::~Data() { diff --git a/src/sim/process.cc b/src/sim/process.cc index 55bd2f209b..ec6ac04492 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -40,6 +40,7 @@ #include "base/loader/symtab.hh" #include "base/statistics.hh" #include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "mem/page_table.hh" #include "mem/physical.hh" @@ -53,7 +54,6 @@ #include "sim/syscall_emul.hh" #include "sim/system.hh" -#include "arch/isa_specific.hh" #if THE_ISA == ALPHA_ISA #include "arch/alpha/linux/process.hh" #include "arch/alpha/tru64/process.hh" diff --git a/src/sim/process.hh b/src/sim/process.hh index 05a48071a3..7922ce0732 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -47,9 +47,11 @@ #include "arch/registers.hh" #include "base/statistics.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "sim/sim_object.hh" #include "sim/syscallreturn.hh" +class BaseRemoteGDB; class GDBListener; class PageTable; class ProcessParams; @@ -58,10 +60,6 @@ class SyscallDesc; class System; class ThreadContext; class TranslatingPort; -namespace TheISA -{ - class RemoteGDB; -} template struct AuxVector @@ -94,7 +92,7 @@ class Process : public SimObject std::vector contextIds; // remote gdb objects - std::vector remoteGDB; + std::vector remoteGDB; std::vector gdbListen; bool breakpoint(); diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 6182150d40..cf063818b8 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -35,10 +35,10 @@ #include #include -#include "config/full_system.hh" - #include "arch/vtophys.hh" #include "base/debug.hh" +#include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "cpu/quiesce_event.hh" diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 811bdb73a8..bd66594afe 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -38,12 +38,12 @@ #include "sim/syscall_emul.hh" #include "base/chunk_generator.hh" #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "mem/page_table.hh" #include "sim/process.hh" #include "sim/system.hh" - #include "sim/sim_exit.hh" using namespace std; diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index c00edfdc61..c9ce4b14fb 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -55,6 +55,7 @@ #include "base/misc.hh" #include "base/trace.hh" #include "base/types.hh" +#include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "mem/translating_port.hh" diff --git a/src/sim/system.cc b/src/sim/system.cc index f10167bba2..da77f19958 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -38,11 +38,14 @@ #include "base/loader/symtab.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" +#include "config/full_system.hh" +#include "config/the_isa.hh" #include "mem/mem_object.hh" #include "mem/physical.hh" #include "sim/byteswap.hh" #include "sim/system.hh" #include "sim/debug.hh" + #if FULL_SYSTEM #include "arch/vtophys.hh" #include "kern/kernel_stats.hh" diff --git a/src/sim/system.hh b/src/sim/system.hh index aa89866bd5..eabbc83510 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -45,6 +45,7 @@ #include "mem/port.hh" #include "params/System.hh" #include "sim/sim_object.hh" + #if FULL_SYSTEM #include "kern/system_events.hh" #include "mem/vport.hh" @@ -59,10 +60,7 @@ class PhysicalMemory; class Platform; #endif class GDBListener; -namespace TheISA -{ - class RemoteGDB; -} +class BaseRemoteGDB; class System : public SimObject { @@ -187,7 +185,7 @@ class System : public SimObject #endif public: - std::vector remoteGDB; + std::vector remoteGDB; std::vector gdbListen; bool breakpoint(); From be0d74d6f6a4af96b975b40782bc28cfae78f624 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 18:17:11 -0700 Subject: [PATCH 024/160] ruby: Disable all debug output by default --- src/mem/ruby/config/defaults.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb index 60f32ca14d..160f254115 100644 --- a/src/mem/ruby/config/defaults.rb +++ b/src/mem/ruby/config/defaults.rb @@ -36,7 +36,7 @@ class Debug < LibRubyObject # 1. change protocol_trace = true # 2. enable debug in the Ruby Makefile # 3. set start_time = 1 - default_param :protocol_trace, Boolean, true + default_param :protocol_trace, Boolean, false # a string for filtering debugging output (for all g_debug vars see Debug.h) default_param :filter_string, String, "none" @@ -48,7 +48,7 @@ class Debug < LibRubyObject default_param :start_time, Integer, 1 # sends debugging messages to a output filename - default_param :output_filename, String, "debug_ss" + default_param :output_filename, String, "none" end class Topology < LibRubyObject From bae6a4a4d9ab3953051fb9d1b866172ecfcbccdb Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 18:28:29 -0700 Subject: [PATCH 025/160] ply grammar: Fixup Tokenizer class so you can get lexer arguments --- src/python/m5/util/grammar.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/python/m5/util/grammar.py b/src/python/m5/util/grammar.py index 93c2c84c45..ab5f358688 100644 --- a/src/python/m5/util/grammar.py +++ b/src/python/m5/util/grammar.py @@ -55,6 +55,7 @@ class Tokenizer(object): break yield tok self.input = _input() + self.lexer = lexer def next(self): return self.input.next() @@ -68,6 +69,9 @@ class Tokenizer(object): except StopIteration: return None + def __getattr__(self, attr): + return getattr(self.lexer, attr) + class Grammar(object): def __init__(self, output=None, debug=False): self.yacc_args = {} From baca1f0566b51a24fda506dc95e3baa6265280d4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 18:28:29 -0700 Subject: [PATCH 026/160] isa_parser: Turn the ISA Parser into a subclass of Grammar. This is to prepare for future cleanup where we allow SCons to create a separate grammar class for each ISA --- src/arch/isa_parser.py | 1344 ++++++++++++++++++++-------------------- 1 file changed, 675 insertions(+), 669 deletions(-) diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 23260ca481..f001eff41c 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -34,697 +34,699 @@ import traceback # get type names from types import * -from ply import lex -from ply import yacc +from m5.util.grammar import Grammar -##################################################################### -# -# Lexer -# -# The PLY lexer module takes two things as input: -# - A list of token names (the string list 'tokens') -# - A regular expression describing a match for each token. The -# regexp for token FOO can be provided in two ways: -# - as a string variable named t_FOO -# - as the doc string for a function named t_FOO. In this case, -# the function is also executed, allowing an action to be -# associated with each token match. -# -##################################################################### +class ISAParser(Grammar): + def __init__(self, *args, **kwargs): + super(ISAParser, self).__init__(*args, **kwargs) + self.templateMap = {} -# Reserved words. These are listed separately as they are matched -# using the same regexp as generic IDs, but distinguished in the -# t_ID() function. The PLY documentation suggests this approach. -reserved = ( - 'BITFIELD', 'DECODE', 'DECODER', 'DEFAULT', 'DEF', 'EXEC', 'FORMAT', - 'HEADER', 'LET', 'NAMESPACE', 'OPERAND_TYPES', 'OPERANDS', - 'OUTPUT', 'SIGNED', 'TEMPLATE' + ##################################################################### + # + # Lexer + # + # The PLY lexer module takes two things as input: + # - A list of token names (the string list 'tokens') + # - A regular expression describing a match for each token. The + # regexp for token FOO can be provided in two ways: + # - as a string variable named t_FOO + # - as the doc string for a function named t_FOO. In this case, + # the function is also executed, allowing an action to be + # associated with each token match. + # + ##################################################################### + + # Reserved words. These are listed separately as they are matched + # using the same regexp as generic IDs, but distinguished in the + # t_ID() function. The PLY documentation suggests this approach. + reserved = ( + 'BITFIELD', 'DECODE', 'DECODER', 'DEFAULT', 'DEF', 'EXEC', 'FORMAT', + 'HEADER', 'LET', 'NAMESPACE', 'OPERAND_TYPES', 'OPERANDS', + 'OUTPUT', 'SIGNED', 'TEMPLATE' + ) + + # List of tokens. The lex module requires this. + tokens = reserved + ( + # identifier + 'ID', + + # integer literal + 'INTLIT', + + # string literal + 'STRLIT', + + # code literal + 'CODELIT', + + # ( ) [ ] { } < > , ; . : :: * + 'LPAREN', 'RPAREN', + 'LBRACKET', 'RBRACKET', + 'LBRACE', 'RBRACE', + 'LESS', 'GREATER', 'EQUALS', + 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON', + 'ASTERISK', + + # C preprocessor directives + 'CPPDIRECTIVE' + + # The following are matched but never returned. commented out to + # suppress PLY warning + # newfile directive + # 'NEWFILE', + + # endfile directive + # 'ENDFILE' ) -# List of tokens. The lex module requires this. -tokens = reserved + ( - # identifier - 'ID', + # Regular expressions for token matching + t_LPAREN = r'\(' + t_RPAREN = r'\)' + t_LBRACKET = r'\[' + t_RBRACKET = r'\]' + t_LBRACE = r'\{' + t_RBRACE = r'\}' + t_LESS = r'\<' + t_GREATER = r'\>' + t_EQUALS = r'=' + t_COMMA = r',' + t_SEMI = r';' + t_DOT = r'\.' + t_COLON = r':' + t_DBLCOLON = r'::' + t_ASTERISK = r'\*' - # integer literal - 'INTLIT', + # Identifiers and reserved words + reserved_map = { } + for r in reserved: + reserved_map[r.lower()] = r - # string literal - 'STRLIT', + def t_ID(self, t): + r'[A-Za-z_]\w*' + t.type = self.reserved_map.get(t.value, 'ID') + return t - # code literal - 'CODELIT', + # Integer literal + def t_INTLIT(self, t): + r'(0x[\da-fA-F]+)|\d+' + try: + t.value = int(t.value,0) + except ValueError: + error(t.lexer.lineno, 'Integer value "%s" too large' % t.value) + t.value = 0 + return t - # ( ) [ ] { } < > , ; . : :: * - 'LPAREN', 'RPAREN', - 'LBRACKET', 'RBRACKET', - 'LBRACE', 'RBRACE', - 'LESS', 'GREATER', 'EQUALS', - 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON', - 'ASTERISK', - - # C preprocessor directives - 'CPPDIRECTIVE' - -# The following are matched but never returned. commented out to -# suppress PLY warning - # newfile directive -# 'NEWFILE', - - # endfile directive -# 'ENDFILE' -) - -# Regular expressions for token matching -t_LPAREN = r'\(' -t_RPAREN = r'\)' -t_LBRACKET = r'\[' -t_RBRACKET = r'\]' -t_LBRACE = r'\{' -t_RBRACE = r'\}' -t_LESS = r'\<' -t_GREATER = r'\>' -t_EQUALS = r'=' -t_COMMA = r',' -t_SEMI = r';' -t_DOT = r'\.' -t_COLON = r':' -t_DBLCOLON = r'::' -t_ASTERISK = r'\*' - -# Identifiers and reserved words -reserved_map = { } -for r in reserved: - reserved_map[r.lower()] = r - -def t_ID(t): - r'[A-Za-z_]\w*' - t.type = reserved_map.get(t.value,'ID') - return t - -# Integer literal -def t_INTLIT(t): - r'(0x[\da-fA-F]+)|\d+' - try: - t.value = int(t.value,0) - except ValueError: - error(t.lexer.lineno, 'Integer value "%s" too large' % t.value) - t.value = 0 - return t - -# String literal. Note that these use only single quotes, and -# can span multiple lines. -def t_STRLIT(t): - r"(?m)'([^'])+'" - # strip off quotes - t.value = t.value[1:-1] - t.lexer.lineno += t.value.count('\n') - return t + # String literal. Note that these use only single quotes, and + # can span multiple lines. + def t_STRLIT(self, t): + r"(?m)'([^'])+'" + # strip off quotes + t.value = t.value[1:-1] + t.lexer.lineno += t.value.count('\n') + return t -# "Code literal"... like a string literal, but delimiters are -# '{{' and '}}' so they get formatted nicely under emacs c-mode -def t_CODELIT(t): - r"(?m)\{\{([^\}]|}(?!\}))+\}\}" - # strip off {{ & }} - t.value = t.value[2:-2] - t.lexer.lineno += t.value.count('\n') - return t + # "Code literal"... like a string literal, but delimiters are + # '{{' and '}}' so they get formatted nicely under emacs c-mode + def t_CODELIT(self, t): + r"(?m)\{\{([^\}]|}(?!\}))+\}\}" + # strip off {{ & }} + t.value = t.value[2:-2] + t.lexer.lineno += t.value.count('\n') + return t -def t_CPPDIRECTIVE(t): - r'^\#[^\#].*\n' - t.lexer.lineno += t.value.count('\n') - return t + def t_CPPDIRECTIVE(self, t): + r'^\#[^\#].*\n' + t.lexer.lineno += t.value.count('\n') + return t -def t_NEWFILE(t): - r'^\#\#newfile\s+"[\w/.-]*"' - fileNameStack.push((t.value[11:-1], t.lexer.lineno)) - t.lexer.lineno = 0 + def t_NEWFILE(self, t): + r'^\#\#newfile\s+"[\w/.-]*"' + fileNameStack.push((t.value[11:-1], t.lexer.lineno)) + t.lexer.lineno = 0 -def t_ENDFILE(t): - r'^\#\#endfile' - (old_filename, t.lexer.lineno) = fileNameStack.pop() + def t_ENDFILE(self, t): + r'^\#\#endfile' + (old_filename, t.lexer.lineno) = fileNameStack.pop() -# -# The functions t_NEWLINE, t_ignore, and t_error are -# special for the lex module. -# + # + # The functions t_NEWLINE, t_ignore, and t_error are + # special for the lex module. + # -# Newlines -def t_NEWLINE(t): - r'\n+' - t.lexer.lineno += t.value.count('\n') + # Newlines + def t_NEWLINE(self, t): + r'\n+' + t.lexer.lineno += t.value.count('\n') -# Comments -def t_comment(t): - r'//.*' + # Comments + def t_comment(self, t): + r'//.*' -# Completely ignored characters -t_ignore = ' \t\x0c' + # Completely ignored characters + t_ignore = ' \t\x0c' -# Error handler -def t_error(t): - error(t.lexer.lineno, "illegal character '%s'" % t.value[0]) - t.skip(1) + # Error handler + def t_error(self, t): + error(t.lexer.lineno, "illegal character '%s'" % t.value[0]) + t.skip(1) -# Build the lexer -lexer = lex.lex() + ##################################################################### + # + # Parser + # + # Every function whose name starts with 'p_' defines a grammar + # rule. The rule is encoded in the function's doc string, while + # the function body provides the action taken when the rule is + # matched. The argument to each function is a list of the values + # of the rule's symbols: t[0] for the LHS, and t[1..n] for the + # symbols on the RHS. For tokens, the value is copied from the + # t.value attribute provided by the lexer. For non-terminals, the + # value is assigned by the producing rule; i.e., the job of the + # grammar rule function is to set the value for the non-terminal + # on the LHS (by assigning to t[0]). + ##################################################################### -##################################################################### -# -# Parser -# -# Every function whose name starts with 'p_' defines a grammar rule. -# The rule is encoded in the function's doc string, while the -# function body provides the action taken when the rule is matched. -# The argument to each function is a list of the values of the -# rule's symbols: t[0] for the LHS, and t[1..n] for the symbols -# on the RHS. For tokens, the value is copied from the t.value -# attribute provided by the lexer. For non-terminals, the value -# is assigned by the producing rule; i.e., the job of the grammar -# rule function is to set the value for the non-terminal on the LHS -# (by assigning to t[0]). -##################################################################### - -# The LHS of the first grammar rule is used as the start symbol -# (in this case, 'specification'). Note that this rule enforces -# that there will be exactly one namespace declaration, with 0 or more -# global defs/decls before and after it. The defs & decls before -# the namespace decl will be outside the namespace; those after -# will be inside. The decoder function is always inside the namespace. -def p_specification(t): - 'specification : opt_defs_and_outputs name_decl opt_defs_and_outputs decode_block' - global_code = t[1] - isa_name = t[2] - namespace = isa_name + "Inst" - # wrap the decode block as a function definition - t[4].wrap_decode_block(''' + # The LHS of the first grammar rule is used as the start symbol + # (in this case, 'specification'). Note that this rule enforces + # that there will be exactly one namespace declaration, with 0 or + # more global defs/decls before and after it. The defs & decls + # before the namespace decl will be outside the namespace; those + # after will be inside. The decoder function is always inside the + # namespace. + def p_specification(self, t): + 'specification : opt_defs_and_outputs name_decl opt_defs_and_outputs decode_block' + global_code = t[1] + isa_name = t[2] + namespace = isa_name + "Inst" + # wrap the decode block as a function definition + t[4].wrap_decode_block(''' StaticInstPtr %(isa_name)s::decodeInst(%(isa_name)s::ExtMachInst machInst) { using namespace %(namespace)s; ''' % vars(), '}') - # both the latter output blocks and the decode block are in the namespace - namespace_code = t[3] + t[4] - # pass it all back to the caller of yacc.parse() - t[0] = (isa_name, namespace, global_code, namespace_code) - -# ISA name declaration looks like "namespace ;" -def p_name_decl(t): - 'name_decl : NAMESPACE ID SEMI' - t[0] = t[2] - -# 'opt_defs_and_outputs' is a possibly empty sequence of -# def and/or output statements. -def p_opt_defs_and_outputs_0(t): - 'opt_defs_and_outputs : empty' - t[0] = GenCode() - -def p_opt_defs_and_outputs_1(t): - 'opt_defs_and_outputs : defs_and_outputs' - t[0] = t[1] - -def p_defs_and_outputs_0(t): - 'defs_and_outputs : def_or_output' - t[0] = t[1] - -def p_defs_and_outputs_1(t): - 'defs_and_outputs : defs_and_outputs def_or_output' - t[0] = t[1] + t[2] - -# The list of possible definition/output statements. -def p_def_or_output(t): - '''def_or_output : def_format - | def_bitfield - | def_bitfield_struct - | def_template - | def_operand_types - | def_operands - | output_header - | output_decoder - | output_exec - | global_let''' - t[0] = t[1] - -# Output blocks 'output {{...}}' (C++ code blocks) are copied -# directly to the appropriate output section. - - -# Protect any non-dict-substitution '%'s in a format string -# (i.e. those not followed by '(') -def protect_non_subst_percents(s): - return re.sub(r'%(?!\()', '%%', s) - -# Massage output block by substituting in template definitions and bit -# operators. We handle '%'s embedded in the string that don't -# indicate template substitutions (or CPU-specific symbols, which get -# handled in GenCode) by doubling them first so that the format -# operation will reduce them back to single '%'s. -def process_output(s): - s = protect_non_subst_percents(s) - # protects cpu-specific symbols too - s = protect_cpu_symbols(s) - return substBitOps(s % templateMap) - -def p_output_header(t): - 'output_header : OUTPUT HEADER CODELIT SEMI' - t[0] = GenCode(header_output = process_output(t[3])) - -def p_output_decoder(t): - 'output_decoder : OUTPUT DECODER CODELIT SEMI' - t[0] = GenCode(decoder_output = process_output(t[3])) - -def p_output_exec(t): - 'output_exec : OUTPUT EXEC CODELIT SEMI' - t[0] = GenCode(exec_output = process_output(t[3])) - -# global let blocks 'let {{...}}' (Python code blocks) are executed -# directly when seen. Note that these execute in a special variable -# context 'exportContext' to prevent the code from polluting this -# script's namespace. -def p_global_let(t): - 'global_let : LET CODELIT SEMI' - updateExportContext() - exportContext["header_output"] = '' - exportContext["decoder_output"] = '' - exportContext["exec_output"] = '' - exportContext["decode_block"] = '' - try: - exec fixPythonIndentation(t[2]) in exportContext - except Exception, exc: - error(t.lexer.lineno, - 'error: %s in global let block "%s".' % (exc, t[2])) - t[0] = GenCode(header_output = exportContext["header_output"], - decoder_output = exportContext["decoder_output"], - exec_output = exportContext["exec_output"], - decode_block = exportContext["decode_block"]) - -# Define the mapping from operand type extensions to C++ types and bit -# widths (stored in operandTypeMap). -def p_def_operand_types(t): - 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI' - try: - userDict = eval('{' + t[3] + '}') - except Exception, exc: - error(t.lexer.lineno, - 'error: %s in def operand_types block "%s".' % (exc, t[3])) - buildOperandTypeMap(userDict, t.lexer.lineno) - t[0] = GenCode() # contributes nothing to the output C++ file - -# Define the mapping from operand names to operand classes and other -# traits. Stored in operandNameMap. -def p_def_operands(t): - 'def_operands : DEF OPERANDS CODELIT SEMI' - if not globals().has_key('operandTypeMap'): - error(t.lexer.lineno, - 'error: operand types must be defined before operands') - try: - userDict = eval('{' + t[3] + '}', exportContext) - except Exception, exc: - error(t.lexer.lineno, - 'error: %s in def operands block "%s".' % (exc, t[3])) - buildOperandNameMap(userDict, t.lexer.lineno) - t[0] = GenCode() # contributes nothing to the output C++ file - -# A bitfield definition looks like: -# 'def [signed] bitfield [:]' -# This generates a preprocessor macro in the output file. -def p_def_bitfield_0(t): - 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI' - expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8]) - if (t[2] == 'signed'): - expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr) - hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) - t[0] = GenCode(header_output = hash_define) - -# alternate form for single bit: 'def [signed] bitfield []' -def p_def_bitfield_1(t): - 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI' - expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6]) - if (t[2] == 'signed'): - expr = 'sext<%d>(%s)' % (1, expr) - hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) - t[0] = GenCode(header_output = hash_define) - -# alternate form for structure member: 'def bitfield ' -def p_def_bitfield_struct(t): - 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI' - if (t[2] != ''): - error(t.lexer.lineno, 'error: structure bitfields are always unsigned.') - expr = 'machInst.%s' % t[5] - hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) - t[0] = GenCode(header_output = hash_define) - -def p_id_with_dot_0(t): - 'id_with_dot : ID' - t[0] = t[1] - -def p_id_with_dot_1(t): - 'id_with_dot : ID DOT id_with_dot' - t[0] = t[1] + t[2] + t[3] - -def p_opt_signed_0(t): - 'opt_signed : SIGNED' - t[0] = t[1] - -def p_opt_signed_1(t): - 'opt_signed : empty' - t[0] = '' - -# Global map variable to hold templates -templateMap = {} - -def p_def_template(t): - 'def_template : DEF TEMPLATE ID CODELIT SEMI' - templateMap[t[3]] = Template(t[4]) - t[0] = GenCode() - -# An instruction format definition looks like -# "def format () {{...}};" -def p_def_format(t): - 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI' - (id, params, code) = (t[3], t[5], t[7]) - defFormat(id, params, code, t.lexer.lineno) - t[0] = GenCode() - -# The formal parameter list for an instruction format is a possibly -# empty list of comma-separated parameters. Positional (standard, -# non-keyword) parameters must come first, followed by keyword -# parameters, followed by a '*foo' parameter that gets excess -# positional arguments (as in Python). Each of these three parameter -# categories is optional. -# -# Note that we do not support the '**foo' parameter for collecting -# otherwise undefined keyword args. Otherwise the parameter list is -# (I believe) identical to what is supported in Python. -# -# The param list generates a tuple, where the first element is a list of -# the positional params and the second element is a dict containing the -# keyword params. -def p_param_list_0(t): - 'param_list : positional_param_list COMMA nonpositional_param_list' - t[0] = t[1] + t[3] - -def p_param_list_1(t): - '''param_list : positional_param_list - | nonpositional_param_list''' - t[0] = t[1] - -def p_positional_param_list_0(t): - 'positional_param_list : empty' - t[0] = [] - -def p_positional_param_list_1(t): - 'positional_param_list : ID' - t[0] = [t[1]] - -def p_positional_param_list_2(t): - 'positional_param_list : positional_param_list COMMA ID' - t[0] = t[1] + [t[3]] - -def p_nonpositional_param_list_0(t): - 'nonpositional_param_list : keyword_param_list COMMA excess_args_param' - t[0] = t[1] + t[3] - -def p_nonpositional_param_list_1(t): - '''nonpositional_param_list : keyword_param_list - | excess_args_param''' - t[0] = t[1] - -def p_keyword_param_list_0(t): - 'keyword_param_list : keyword_param' - t[0] = [t[1]] - -def p_keyword_param_list_1(t): - 'keyword_param_list : keyword_param_list COMMA keyword_param' - t[0] = t[1] + [t[3]] - -def p_keyword_param(t): - 'keyword_param : ID EQUALS expr' - t[0] = t[1] + ' = ' + t[3].__repr__() - -def p_excess_args_param(t): - 'excess_args_param : ASTERISK ID' - # Just concatenate them: '*ID'. Wrap in list to be consistent - # with positional_param_list and keyword_param_list. - t[0] = [t[1] + t[2]] - -# End of format definition-related rules. -############## - -# -# A decode block looks like: -# decode [, ]* [default ] { ... } -# -def p_decode_block(t): - 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE' - default_defaults = defaultStack.pop() - codeObj = t[5] - # use the "default defaults" only if there was no explicit - # default statement in decode_stmt_list - if not codeObj.has_decode_default: - codeObj += default_defaults - codeObj.wrap_decode_block('switch (%s) {\n' % t[2], '}\n') - t[0] = codeObj - -# The opt_default statement serves only to push the "default defaults" -# onto defaultStack. This value will be used by nested decode blocks, -# and used and popped off when the current decode_block is processed -# (in p_decode_block() above). -def p_opt_default_0(t): - 'opt_default : empty' - # no default specified: reuse the one currently at the top of the stack - defaultStack.push(defaultStack.top()) - # no meaningful value returned - t[0] = None - -def p_opt_default_1(t): - 'opt_default : DEFAULT inst' - # push the new default - codeObj = t[2] - codeObj.wrap_decode_block('\ndefault:\n', 'break;\n') - defaultStack.push(codeObj) - # no meaningful value returned - t[0] = None - -def p_decode_stmt_list_0(t): - 'decode_stmt_list : decode_stmt' - t[0] = t[1] - -def p_decode_stmt_list_1(t): - 'decode_stmt_list : decode_stmt decode_stmt_list' - if (t[1].has_decode_default and t[2].has_decode_default): - error(t.lexer.lineno, 'Two default cases in decode block') - t[0] = t[1] + t[2] - -# -# Decode statement rules -# -# There are four types of statements allowed in a decode block: -# 1. Format blocks 'format { ... }' -# 2. Nested decode blocks -# 3. Instruction definitions. -# 4. C preprocessor directives. - - -# Preprocessor directives found in a decode statement list are passed -# through to the output, replicated to all of the output code -# streams. This works well for ifdefs, so we can ifdef out both the -# declarations and the decode cases generated by an instruction -# definition. Handling them as part of the grammar makes it easy to -# keep them in the right place with respect to the code generated by -# the other statements. -def p_decode_stmt_cpp(t): - 'decode_stmt : CPPDIRECTIVE' - t[0] = GenCode(t[1], t[1], t[1], t[1]) - -# A format block 'format { ... }' sets the default instruction -# format used to handle instruction definitions inside the block. -# This format can be overridden by using an explicit format on the -# instruction definition or with a nested format block. -def p_decode_stmt_format(t): - 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE' - # The format will be pushed on the stack when 'push_format_id' is - # processed (see below). Once the parser has recognized the full - # production (though the right brace), we're done with the format, - # so now we can pop it. - formatStack.pop() - t[0] = t[4] - -# This rule exists so we can set the current format (& push the stack) -# when we recognize the format name part of the format block. -def p_push_format_id(t): - 'push_format_id : ID' - try: - formatStack.push(formatMap[t[1]]) - t[0] = ('', '// format %s' % t[1]) - except KeyError: - error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1]) - -# Nested decode block: if the value of the current field matches the -# specified constant, do a nested decode on some other field. -def p_decode_stmt_decode(t): - 'decode_stmt : case_label COLON decode_block' - label = t[1] - codeObj = t[3] - # just wrap the decoding code from the block as a case in the - # outer switch statement. - codeObj.wrap_decode_block('\n%s:\n' % label) - codeObj.has_decode_default = (label == 'default') - t[0] = codeObj - -# Instruction definition (finally!). -def p_decode_stmt_inst(t): - 'decode_stmt : case_label COLON inst SEMI' - label = t[1] - codeObj = t[3] - codeObj.wrap_decode_block('\n%s:' % label, 'break;\n') - codeObj.has_decode_default = (label == 'default') - t[0] = codeObj - -# The case label is either a list of one or more constants or 'default' -def p_case_label_0(t): - 'case_label : intlit_list' - t[0] = ': '.join(map(lambda a: 'case %#x' % a, t[1])) - -def p_case_label_1(t): - 'case_label : DEFAULT' - t[0] = 'default' - -# -# The constant list for a decode case label must be non-empty, but may have -# one or more comma-separated integer literals in it. -# -def p_intlit_list_0(t): - 'intlit_list : INTLIT' - t[0] = [t[1]] - -def p_intlit_list_1(t): - 'intlit_list : intlit_list COMMA INTLIT' - t[0] = t[1] - t[0].append(t[3]) - -# Define an instruction using the current instruction format (specified -# by an enclosing format block). -# "()" -def p_inst_0(t): - 'inst : ID LPAREN arg_list RPAREN' - # Pass the ID and arg list to the current format class to deal with. - currentFormat = formatStack.top() - codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno) - args = ','.join(map(str, t[3])) - args = re.sub('(?m)^', '//', args) - args = re.sub('^//', '', args) - comment = '\n// %s::%s(%s)\n' % (currentFormat.id, t[1], args) - codeObj.prepend_all(comment) - t[0] = codeObj - -# Define an instruction using an explicitly specified format: -# "::()" -def p_inst_1(t): - 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN' - try: - format = formatMap[t[1]] - except KeyError: - error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1]) - codeObj = format.defineInst(t[3], t[5], t.lexer.lineno) - comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5]) - codeObj.prepend_all(comment) - t[0] = codeObj - -# The arg list generates a tuple, where the first element is a list of -# the positional args and the second element is a dict containing the -# keyword args. -def p_arg_list_0(t): - 'arg_list : positional_arg_list COMMA keyword_arg_list' - t[0] = ( t[1], t[3] ) - -def p_arg_list_1(t): - 'arg_list : positional_arg_list' - t[0] = ( t[1], {} ) - -def p_arg_list_2(t): - 'arg_list : keyword_arg_list' - t[0] = ( [], t[1] ) - -def p_positional_arg_list_0(t): - 'positional_arg_list : empty' - t[0] = [] - -def p_positional_arg_list_1(t): - 'positional_arg_list : expr' - t[0] = [t[1]] - -def p_positional_arg_list_2(t): - 'positional_arg_list : positional_arg_list COMMA expr' - t[0] = t[1] + [t[3]] - -def p_keyword_arg_list_0(t): - 'keyword_arg_list : keyword_arg' - t[0] = t[1] - -def p_keyword_arg_list_1(t): - 'keyword_arg_list : keyword_arg_list COMMA keyword_arg' - t[0] = t[1] - t[0].update(t[3]) - -def p_keyword_arg(t): - 'keyword_arg : ID EQUALS expr' - t[0] = { t[1] : t[3] } - -# -# Basic expressions. These constitute the argument values of -# "function calls" (i.e. instruction definitions in the decode block) -# and default values for formal parameters of format functions. -# -# Right now, these are either strings, integers, or (recursively) -# lists of exprs (using Python square-bracket list syntax). Note that -# bare identifiers are trated as string constants here (since there -# isn't really a variable namespace to refer to). -# -def p_expr_0(t): - '''expr : ID - | INTLIT - | STRLIT - | CODELIT''' - t[0] = t[1] - -def p_expr_1(t): - '''expr : LBRACKET list_expr RBRACKET''' - t[0] = t[2] - -def p_list_expr_0(t): - 'list_expr : expr' - t[0] = [t[1]] - -def p_list_expr_1(t): - 'list_expr : list_expr COMMA expr' - t[0] = t[1] + [t[3]] - -def p_list_expr_2(t): - 'list_expr : empty' - t[0] = [] - -# -# Empty production... use in other rules for readability. -# -def p_empty(t): - 'empty :' - pass - -# Parse error handler. Note that the argument here is the offending -# *token*, not a grammar symbol (hence the need to use t.value) -def p_error(t): - if t: - error(t.lexer.lineno, "syntax error at '%s'" % t.value) - else: - error(0, "unknown syntax error", True) - -# END OF GRAMMAR RULES -# + # both the latter output blocks and the decode block are in + # the namespace + namespace_code = t[3] + t[4] + # pass it all back to the caller of yacc.parse() + t[0] = (isa_name, namespace, global_code, namespace_code) + + # ISA name declaration looks like "namespace ;" + def p_name_decl(self, t): + 'name_decl : NAMESPACE ID SEMI' + t[0] = t[2] + + # 'opt_defs_and_outputs' is a possibly empty sequence of + # def and/or output statements. + def p_opt_defs_and_outputs_0(self, t): + 'opt_defs_and_outputs : empty' + t[0] = GenCode() + + def p_opt_defs_and_outputs_1(self, t): + 'opt_defs_and_outputs : defs_and_outputs' + t[0] = t[1] + + def p_defs_and_outputs_0(self, t): + 'defs_and_outputs : def_or_output' + t[0] = t[1] + + def p_defs_and_outputs_1(self, t): + 'defs_and_outputs : defs_and_outputs def_or_output' + t[0] = t[1] + t[2] + + # The list of possible definition/output statements. + def p_def_or_output(self, t): + '''def_or_output : def_format + | def_bitfield + | def_bitfield_struct + | def_template + | def_operand_types + | def_operands + | output_header + | output_decoder + | output_exec + | global_let''' + t[0] = t[1] + + # Output blocks 'output {{...}}' (C++ code blocks) are copied + # directly to the appropriate output section. + + # Massage output block by substituting in template definitions and + # bit operators. We handle '%'s embedded in the string that don't + # indicate template substitutions (or CPU-specific symbols, which + # get handled in GenCode) by doubling them first so that the + # format operation will reduce them back to single '%'s. + def process_output(self, s): + s = protect_non_subst_percents(s) + # protects cpu-specific symbols too + s = protect_cpu_symbols(s) + return substBitOps(s % self.templateMap) + + def p_output_header(self, t): + 'output_header : OUTPUT HEADER CODELIT SEMI' + t[0] = GenCode(header_output = self.process_output(t[3])) + + def p_output_decoder(self, t): + 'output_decoder : OUTPUT DECODER CODELIT SEMI' + t[0] = GenCode(decoder_output = self.process_output(t[3])) + + def p_output_exec(self, t): + 'output_exec : OUTPUT EXEC CODELIT SEMI' + t[0] = GenCode(exec_output = self.process_output(t[3])) + + # global let blocks 'let {{...}}' (Python code blocks) are + # executed directly when seen. Note that these execute in a + # special variable context 'exportContext' to prevent the code + # from polluting this script's namespace. + def p_global_let(self, t): + 'global_let : LET CODELIT SEMI' + updateExportContext() + exportContext["header_output"] = '' + exportContext["decoder_output"] = '' + exportContext["exec_output"] = '' + exportContext["decode_block"] = '' + try: + exec fixPythonIndentation(t[2]) in exportContext + except Exception, exc: + error(t.lexer.lineno, + 'error: %s in global let block "%s".' % (exc, t[2])) + t[0] = GenCode(header_output = exportContext["header_output"], + decoder_output = exportContext["decoder_output"], + exec_output = exportContext["exec_output"], + decode_block = exportContext["decode_block"]) + + # Define the mapping from operand type extensions to C++ types and + # bit widths (stored in operandTypeMap). + def p_def_operand_types(self, t): + 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI' + try: + userDict = eval('{' + t[3] + '}') + except Exception, exc: + error(t.lexer.lineno, + 'error: %s in def operand_types block "%s".' % (exc, t[3])) + buildOperandTypeMap(userDict, t.lexer.lineno) + t[0] = GenCode() # contributes nothing to the output C++ file + + # Define the mapping from operand names to operand classes and + # other traits. Stored in operandNameMap. + def p_def_operands(self, t): + 'def_operands : DEF OPERANDS CODELIT SEMI' + if not globals().has_key('operandTypeMap'): + error(t.lexer.lineno, + 'error: operand types must be defined before operands') + try: + userDict = eval('{' + t[3] + '}', exportContext) + except Exception, exc: + error(t.lexer.lineno, + 'error: %s in def operands block "%s".' % (exc, t[3])) + buildOperandNameMap(userDict, t.lexer.lineno) + t[0] = GenCode() # contributes nothing to the output C++ file + + # A bitfield definition looks like: + # 'def [signed] bitfield [:]' + # This generates a preprocessor macro in the output file. + def p_def_bitfield_0(self, t): + 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI' + expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8]) + if (t[2] == 'signed'): + expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr) + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + + # alternate form for single bit: 'def [signed] bitfield []' + def p_def_bitfield_1(self, t): + 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI' + expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6]) + if (t[2] == 'signed'): + expr = 'sext<%d>(%s)' % (1, expr) + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + + # alternate form for structure member: 'def bitfield ' + def p_def_bitfield_struct(self, t): + 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI' + if (t[2] != ''): + error(t.lexer.lineno, + 'error: structure bitfields are always unsigned.') + expr = 'machInst.%s' % t[5] + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + + def p_id_with_dot_0(self, t): + 'id_with_dot : ID' + t[0] = t[1] + + def p_id_with_dot_1(self, t): + 'id_with_dot : ID DOT id_with_dot' + t[0] = t[1] + t[2] + t[3] + + def p_opt_signed_0(self, t): + 'opt_signed : SIGNED' + t[0] = t[1] + + def p_opt_signed_1(self, t): + 'opt_signed : empty' + t[0] = '' + + def p_def_template(self, t): + 'def_template : DEF TEMPLATE ID CODELIT SEMI' + self.templateMap[t[3]] = Template(t[4]) + t[0] = GenCode() + + # An instruction format definition looks like + # "def format () {{...}};" + def p_def_format(self, t): + 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI' + (id, params, code) = (t[3], t[5], t[7]) + defFormat(id, params, code, t.lexer.lineno) + t[0] = GenCode() + + # The formal parameter list for an instruction format is a + # possibly empty list of comma-separated parameters. Positional + # (standard, non-keyword) parameters must come first, followed by + # keyword parameters, followed by a '*foo' parameter that gets + # excess positional arguments (as in Python). Each of these three + # parameter categories is optional. + # + # Note that we do not support the '**foo' parameter for collecting + # otherwise undefined keyword args. Otherwise the parameter list + # is (I believe) identical to what is supported in Python. + # + # The param list generates a tuple, where the first element is a + # list of the positional params and the second element is a dict + # containing the keyword params. + def p_param_list_0(self, t): + 'param_list : positional_param_list COMMA nonpositional_param_list' + t[0] = t[1] + t[3] + + def p_param_list_1(self, t): + '''param_list : positional_param_list + | nonpositional_param_list''' + t[0] = t[1] + + def p_positional_param_list_0(self, t): + 'positional_param_list : empty' + t[0] = [] + + def p_positional_param_list_1(self, t): + 'positional_param_list : ID' + t[0] = [t[1]] + + def p_positional_param_list_2(self, t): + 'positional_param_list : positional_param_list COMMA ID' + t[0] = t[1] + [t[3]] + + def p_nonpositional_param_list_0(self, t): + 'nonpositional_param_list : keyword_param_list COMMA excess_args_param' + t[0] = t[1] + t[3] + + def p_nonpositional_param_list_1(self, t): + '''nonpositional_param_list : keyword_param_list + | excess_args_param''' + t[0] = t[1] + + def p_keyword_param_list_0(self, t): + 'keyword_param_list : keyword_param' + t[0] = [t[1]] + + def p_keyword_param_list_1(self, t): + 'keyword_param_list : keyword_param_list COMMA keyword_param' + t[0] = t[1] + [t[3]] + + def p_keyword_param(self, t): + 'keyword_param : ID EQUALS expr' + t[0] = t[1] + ' = ' + t[3].__repr__() + + def p_excess_args_param(self, t): + 'excess_args_param : ASTERISK ID' + # Just concatenate them: '*ID'. Wrap in list to be consistent + # with positional_param_list and keyword_param_list. + t[0] = [t[1] + t[2]] + + # End of format definition-related rules. + ############## + + # + # A decode block looks like: + # decode [, ]* [default ] { ... } + # + def p_decode_block(self, t): + 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE' + default_defaults = defaultStack.pop() + codeObj = t[5] + # use the "default defaults" only if there was no explicit + # default statement in decode_stmt_list + if not codeObj.has_decode_default: + codeObj += default_defaults + codeObj.wrap_decode_block('switch (%s) {\n' % t[2], '}\n') + t[0] = codeObj + + # The opt_default statement serves only to push the "default + # defaults" onto defaultStack. This value will be used by nested + # decode blocks, and used and popped off when the current + # decode_block is processed (in p_decode_block() above). + def p_opt_default_0(self, t): + 'opt_default : empty' + # no default specified: reuse the one currently at the top of + # the stack + defaultStack.push(defaultStack.top()) + # no meaningful value returned + t[0] = None + + def p_opt_default_1(self, t): + 'opt_default : DEFAULT inst' + # push the new default + codeObj = t[2] + codeObj.wrap_decode_block('\ndefault:\n', 'break;\n') + defaultStack.push(codeObj) + # no meaningful value returned + t[0] = None + + def p_decode_stmt_list_0(self, t): + 'decode_stmt_list : decode_stmt' + t[0] = t[1] + + def p_decode_stmt_list_1(self, t): + 'decode_stmt_list : decode_stmt decode_stmt_list' + if (t[1].has_decode_default and t[2].has_decode_default): + error(t.lexer.lineno, 'Two default cases in decode block') + t[0] = t[1] + t[2] + + # + # Decode statement rules + # + # There are four types of statements allowed in a decode block: + # 1. Format blocks 'format { ... }' + # 2. Nested decode blocks + # 3. Instruction definitions. + # 4. C preprocessor directives. + + + # Preprocessor directives found in a decode statement list are + # passed through to the output, replicated to all of the output + # code streams. This works well for ifdefs, so we can ifdef out + # both the declarations and the decode cases generated by an + # instruction definition. Handling them as part of the grammar + # makes it easy to keep them in the right place with respect to + # the code generated by the other statements. + def p_decode_stmt_cpp(self, t): + 'decode_stmt : CPPDIRECTIVE' + t[0] = GenCode(t[1], t[1], t[1], t[1]) + + # A format block 'format { ... }' sets the default + # instruction format used to handle instruction definitions inside + # the block. This format can be overridden by using an explicit + # format on the instruction definition or with a nested format + # block. + def p_decode_stmt_format(self, t): + 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE' + # The format will be pushed on the stack when 'push_format_id' + # is processed (see below). Once the parser has recognized + # the full production (though the right brace), we're done + # with the format, so now we can pop it. + formatStack.pop() + t[0] = t[4] + + # This rule exists so we can set the current format (& push the + # stack) when we recognize the format name part of the format + # block. + def p_push_format_id(self, t): + 'push_format_id : ID' + try: + formatStack.push(formatMap[t[1]]) + t[0] = ('', '// format %s' % t[1]) + except KeyError: + error(t.lexer.lineno, + 'instruction format "%s" not defined.' % t[1]) + + # Nested decode block: if the value of the current field matches + # the specified constant, do a nested decode on some other field. + def p_decode_stmt_decode(self, t): + 'decode_stmt : case_label COLON decode_block' + label = t[1] + codeObj = t[3] + # just wrap the decoding code from the block as a case in the + # outer switch statement. + codeObj.wrap_decode_block('\n%s:\n' % label) + codeObj.has_decode_default = (label == 'default') + t[0] = codeObj + + # Instruction definition (finally!). + def p_decode_stmt_inst(self, t): + 'decode_stmt : case_label COLON inst SEMI' + label = t[1] + codeObj = t[3] + codeObj.wrap_decode_block('\n%s:' % label, 'break;\n') + codeObj.has_decode_default = (label == 'default') + t[0] = codeObj + + # The case label is either a list of one or more constants or + # 'default' + def p_case_label_0(self, t): + 'case_label : intlit_list' + t[0] = ': '.join(map(lambda a: 'case %#x' % a, t[1])) + + def p_case_label_1(self, t): + 'case_label : DEFAULT' + t[0] = 'default' + + # + # The constant list for a decode case label must be non-empty, but + # may have one or more comma-separated integer literals in it. + # + def p_intlit_list_0(self, t): + 'intlit_list : INTLIT' + t[0] = [t[1]] + + def p_intlit_list_1(self, t): + 'intlit_list : intlit_list COMMA INTLIT' + t[0] = t[1] + t[0].append(t[3]) + + # Define an instruction using the current instruction format + # (specified by an enclosing format block). + # "()" + def p_inst_0(self, t): + 'inst : ID LPAREN arg_list RPAREN' + # Pass the ID and arg list to the current format class to deal with. + currentFormat = formatStack.top() + codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno) + args = ','.join(map(str, t[3])) + args = re.sub('(?m)^', '//', args) + args = re.sub('^//', '', args) + comment = '\n// %s::%s(%s)\n' % (currentFormat.id, t[1], args) + codeObj.prepend_all(comment) + t[0] = codeObj + + # Define an instruction using an explicitly specified format: + # "::()" + def p_inst_1(self, t): + 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN' + try: + format = formatMap[t[1]] + except KeyError: + error(t.lexer.lineno, + 'instruction format "%s" not defined.' % t[1]) + codeObj = format.defineInst(t[3], t[5], t.lexer.lineno) + comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5]) + codeObj.prepend_all(comment) + t[0] = codeObj + + # The arg list generates a tuple, where the first element is a + # list of the positional args and the second element is a dict + # containing the keyword args. + def p_arg_list_0(self, t): + 'arg_list : positional_arg_list COMMA keyword_arg_list' + t[0] = ( t[1], t[3] ) + + def p_arg_list_1(self, t): + 'arg_list : positional_arg_list' + t[0] = ( t[1], {} ) + + def p_arg_list_2(self, t): + 'arg_list : keyword_arg_list' + t[0] = ( [], t[1] ) + + def p_positional_arg_list_0(self, t): + 'positional_arg_list : empty' + t[0] = [] + + def p_positional_arg_list_1(self, t): + 'positional_arg_list : expr' + t[0] = [t[1]] + + def p_positional_arg_list_2(self, t): + 'positional_arg_list : positional_arg_list COMMA expr' + t[0] = t[1] + [t[3]] + + def p_keyword_arg_list_0(self, t): + 'keyword_arg_list : keyword_arg' + t[0] = t[1] + + def p_keyword_arg_list_1(self, t): + 'keyword_arg_list : keyword_arg_list COMMA keyword_arg' + t[0] = t[1] + t[0].update(t[3]) + + def p_keyword_arg(self, t): + 'keyword_arg : ID EQUALS expr' + t[0] = { t[1] : t[3] } + + # + # Basic expressions. These constitute the argument values of + # "function calls" (i.e. instruction definitions in the decode + # block) and default values for formal parameters of format + # functions. + # + # Right now, these are either strings, integers, or (recursively) + # lists of exprs (using Python square-bracket list syntax). Note + # that bare identifiers are trated as string constants here (since + # there isn't really a variable namespace to refer to). + # + def p_expr_0(self, t): + '''expr : ID + | INTLIT + | STRLIT + | CODELIT''' + t[0] = t[1] + + def p_expr_1(self, t): + '''expr : LBRACKET list_expr RBRACKET''' + t[0] = t[2] + + def p_list_expr_0(self, t): + 'list_expr : expr' + t[0] = [t[1]] + + def p_list_expr_1(self, t): + 'list_expr : list_expr COMMA expr' + t[0] = t[1] + [t[3]] + + def p_list_expr_2(self, t): + 'list_expr : empty' + t[0] = [] + + # + # Empty production... use in other rules for readability. + # + def p_empty(self, t): + 'empty :' + pass + + # Parse error handler. Note that the argument here is the + # offending *token*, not a grammar symbol (hence the need to use + # t.value) + def p_error(self, t): + if t: + error(t.lexer.lineno, "syntax error at '%s'" % t.value) + else: + error(0, "unknown syntax error", True) + + # END OF GRAMMAR RULES + # Now build the parser. -parser = yacc.yacc() - +parser = ISAParser() ##################################################################### # @@ -761,6 +763,11 @@ def expand_cpu_symbols_to_string(template): def protect_cpu_symbols(template): return re.sub(r'%(?=\(CPU_)', '%%', template) +# Protect any non-dict-substitution '%'s in a format string +# (i.e. those not followed by '(') +def protect_non_subst_percents(s): + return re.sub(r'%(?!\()', '%%', s) + ############### # GenCode class # @@ -834,7 +841,7 @@ exportContext = {} def updateExportContext(): exportContext.update(exportDict(*exportContextSymbols)) - exportContext.update(templateMap) + exportContext.update(parser.templateMap) def exportDict(*symNames): return dict([(s, eval(s)) for s in symNames]) @@ -1044,7 +1051,7 @@ class Template: # Build a dict ('myDict') to use for the template substitution. # Start with the template namespace. Make a copy since we're # going to modify it. - myDict = templateMap.copy() + myDict = parser.templateMap.copy() if isinstance(d, InstObjParams): # If we're dealing with an InstObjParams object, we need @@ -1970,8 +1977,7 @@ def parse_isa_desc(isa_desc_file, output_dir): fileNameStack.push((isa_desc_file, 0)) # Parse it. - (isa_name, namespace, global_code, namespace_code) = \ - parser.parse(isa_desc, lexer=lexer) + (isa_name, namespace, global_code, namespace_code) = parser.parse(isa_desc) # grab the last three path components of isa_desc_file to put in # the output From eb1bd7a2e63f09efa7e65bd9dd6578bf9cfd68ac Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 24 Sep 2009 12:30:53 -0400 Subject: [PATCH 027/160] mips-stats: update regressions of arguments fix --- .../ref/mips/linux/inorder-timing/simout | 8 +- .../ref/mips/linux/inorder-timing/stats.txt | 210 ++++----- .../ref/mips/linux/o3-timing/config.ini | 2 +- .../00.hello/ref/mips/linux/o3-timing/simout | 10 +- .../ref/mips/linux/o3-timing/stats.txt | 424 +++++++++--------- .../ref/mips/linux/simple-atomic/config.ini | 2 +- .../ref/mips/linux/simple-atomic/simout | 10 +- .../ref/mips/linux/simple-atomic/stats.txt | 16 +- .../ref/mips/linux/simple-timing/config.ini | 2 +- .../ref/mips/linux/simple-timing/simout | 10 +- .../ref/mips/linux/simple-timing/stats.txt | 164 +++---- 11 files changed, 429 insertions(+), 429 deletions(-) diff --git a/tests/quick/00.hello/ref/mips/linux/inorder-timing/simout b/tests/quick/00.hello/ref/mips/linux/inorder-timing/simout index 56a68daea3..f04692a1f6 100755 --- a/tests/quick/00.hello/ref/mips/linux/inorder-timing/simout +++ b/tests/quick/00.hello/ref/mips/linux/inorder-timing/simout @@ -5,13 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled May 13 2009 01:40:41 -M5 revision 4c418376e894 6202 default tip -M5 started May 13 2009 01:40:42 +M5 compiled Sep 24 2009 12:19:09 +M5 revision 9bc3e4611009+ 6661+ default tip +M5 started Sep 24 2009 12:19:46 M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/inorder-timing -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/inorder-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 29437500 because target called exit() +Exiting @ tick 29521500 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/inorder-timing/stats.txt b/tests/quick/00.hello/ref/mips/linux/inorder-timing/stats.txt index 577875f3a7..a47f185bcf 100644 --- a/tests/quick/00.hello/ref/mips/linux/inorder-timing/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/inorder-timing/stats.txt @@ -1,44 +1,44 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 23976 # Simulator instruction rate (inst/s) -host_mem_usage 152688 # Number of bytes of host memory used -host_seconds 0.24 # Real time elapsed on the host -host_tick_rate 124659634 # Simulator tick rate (ticks/s) +host_inst_rate 29581 # Simulator instruction rate (inst/s) +host_mem_usage 155804 # Number of bytes of host memory used +host_seconds 0.19 # Real time elapsed on the host +host_tick_rate 153369596 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated -sim_seconds 0.000029 # Number of seconds simulated -sim_ticks 29437500 # Number of ticks simulated -system.cpu.AGEN-Unit.instReqsProcessed 2055 # Number of Instructions Requests that completed in this resource. -system.cpu.Branch-Predictor.instReqsProcessed 5657 # Number of Instructions Requests that completed in this resource. -system.cpu.Branch-Predictor.predictedNotTaken 783 # Number of Branches Predicted As Not Taken (False). +sim_insts 5685 # Number of instructions simulated +sim_seconds 0.000030 # Number of seconds simulated +sim_ticks 29521500 # Number of ticks simulated +system.cpu.AGEN-Unit.instReqsProcessed 2058 # Number of Instructions Requests that completed in this resource. +system.cpu.Branch-Predictor.instReqsProcessed 5686 # Number of Instructions Requests that completed in this resource. +system.cpu.Branch-Predictor.predictedNotTaken 789 # Number of Branches Predicted As Not Taken (False). system.cpu.Branch-Predictor.predictedTaken 96 # Number of Branches Predicted As Taken (True). -system.cpu.Decode-Unit.instReqsProcessed 5657 # Number of Instructions Requests that completed in this resource. -system.cpu.Execution-Unit.instReqsProcessed 3598 # Number of Instructions Requests that completed in this resource. -system.cpu.Execution-Unit.predictedNotTakenIncorrect 515 # Number of Branches Incorrectly Predicted As Not Taken). +system.cpu.Decode-Unit.instReqsProcessed 5686 # Number of Instructions Requests that completed in this resource. +system.cpu.Execution-Unit.instReqsProcessed 3624 # Number of Instructions Requests that completed in this resource. +system.cpu.Execution-Unit.predictedNotTakenIncorrect 516 # Number of Branches Incorrectly Predicted As Not Taken). system.cpu.Execution-Unit.predictedTakenIncorrect 34 # Number of Branches Incorrectly Predicted As Taken. system.cpu.Fetch-Buffer-T0.instReqsProcessed 0 # Number of Instructions Requests that completed in this resource. system.cpu.Fetch-Buffer-T0.instsBypassed 0 # Number of Instructions Bypassed. system.cpu.Fetch-Buffer-T1.instReqsProcessed 0 # Number of Instructions Requests that completed in this resource. system.cpu.Fetch-Buffer-T1.instsBypassed 0 # Number of Instructions Bypassed. -system.cpu.Fetch-Seq-Unit.instReqsProcessed 11315 # Number of Instructions Requests that completed in this resource. -system.cpu.Graduation-Unit.instReqsProcessed 5656 # Number of Instructions Requests that completed in this resource. +system.cpu.Fetch-Seq-Unit.instReqsProcessed 11373 # Number of Instructions Requests that completed in this resource. +system.cpu.Graduation-Unit.instReqsProcessed 5685 # Number of Instructions Requests that completed in this resource. system.cpu.Mult-Div-Unit.divInstReqsProcessed 1 # Number of Divide Requests Processed. system.cpu.Mult-Div-Unit.instReqsProcessed 8 # Number of Instructions Requests that completed in this resource. system.cpu.Mult-Div-Unit.multInstReqsProcessed 3 # Number of Multiply Requests Processed. -system.cpu.RegFile-Manager.instReqsProcessed 10420 # Number of Instructions Requests that completed in this resource. -system.cpu.committedInsts 5656 # Number of Instructions Simulated (Per-Thread) -system.cpu.committedInsts_total 5656 # Number of Instructions Simulated (Total) -system.cpu.cpi 10.409477 # CPI: Cycles Per Instruction (Per-Thread) -system.cpu.cpi_total 10.409477 # CPI: Total CPI of All Threads -system.cpu.dcache.ReadReq_accesses 1131 # number of ReadReq accesses(hits+misses) +system.cpu.RegFile-Manager.instReqsProcessed 10479 # Number of Instructions Requests that completed in this resource. +system.cpu.committedInsts 5685 # Number of Instructions Simulated (Per-Thread) +system.cpu.committedInsts_total 5685 # Number of Instructions Simulated (Total) +system.cpu.cpi 10.385928 # CPI: Cycles Per Instruction (Per-Thread) +system.cpu.cpi_total 10.385928 # CPI: Total CPI of All Threads +system.cpu.dcache.ReadReq_accesses 1134 # number of ReadReq accesses(hits+misses) system.cpu.dcache.ReadReq_avg_miss_latency 56207.317073 # average ReadReq miss latency system.cpu.dcache.ReadReq_avg_mshr_miss_latency 53207.317073 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 1049 # number of ReadReq hits +system.cpu.dcache.ReadReq_hits 1052 # number of ReadReq hits system.cpu.dcache.ReadReq_miss_latency 4609000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.072502 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_miss_rate 0.072310 # miss rate for ReadReq accesses system.cpu.dcache.ReadReq_misses 82 # number of ReadReq misses system.cpu.dcache.ReadReq_mshr_miss_latency 4363000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.072502 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_miss_rate 0.072310 # mshr miss rate for ReadReq accesses system.cpu.dcache.ReadReq_mshr_misses 82 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 924 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 56554.687500 # average WriteReq miss latency @@ -52,48 +52,48 @@ system.cpu.dcache.WriteReq_mshr_miss_rate 0.069264 # m system.cpu.dcache.WriteReq_mshr_misses 64 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 14.568182 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 14.590909 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed -system.cpu.dcache.demand_accesses 2055 # number of demand (read+write) accesses +system.cpu.dcache.demand_accesses 2058 # number of demand (read+write) accesses system.cpu.dcache.demand_avg_miss_latency 56359.589041 # average overall miss latency system.cpu.dcache.demand_avg_mshr_miss_latency 53359.589041 # average overall mshr miss latency -system.cpu.dcache.demand_hits 1909 # number of demand (read+write) hits +system.cpu.dcache.demand_hits 1912 # number of demand (read+write) hits system.cpu.dcache.demand_miss_latency 8228500 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.071046 # miss rate for demand accesses +system.cpu.dcache.demand_miss_rate 0.070943 # miss rate for demand accesses system.cpu.dcache.demand_misses 146 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits system.cpu.dcache.demand_mshr_miss_latency 7790500 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.071046 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_miss_rate 0.070943 # mshr miss rate for demand accesses system.cpu.dcache.demand_mshr_misses 146 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.dcache.overall_accesses 2055 # number of overall (read+write) accesses +system.cpu.dcache.overall_accesses 2058 # number of overall (read+write) accesses system.cpu.dcache.overall_avg_miss_latency 56359.589041 # average overall miss latency system.cpu.dcache.overall_avg_mshr_miss_latency 53359.589041 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 1909 # number of overall hits +system.cpu.dcache.overall_hits 1912 # number of overall hits system.cpu.dcache.overall_miss_latency 8228500 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.071046 # miss rate for overall accesses +system.cpu.dcache.overall_miss_rate 0.070943 # miss rate for overall accesses system.cpu.dcache.overall_misses 146 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits system.cpu.dcache.overall_mshr_miss_latency 7790500 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.071046 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_miss_rate 0.070943 # mshr miss rate for overall accesses system.cpu.dcache.overall_mshr_misses 146 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.dcache.replacements 0 # number of replacements system.cpu.dcache.sampled_refs 132 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 84.205216 # Cycle average of tags in use -system.cpu.dcache.total_refs 1923 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 84.209307 # Cycle average of tags in use +system.cpu.dcache.total_refs 1926 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.dcache.writebacks 0 # number of writebacks -system.cpu.dcache_port.instReqsProcessed 2054 # Number of Instructions Requests that completed in this resource. +system.cpu.dcache_port.instReqsProcessed 2057 # Number of Instructions Requests that completed in this resource. system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits system.cpu.dtb.misses 0 # DTB misses @@ -103,62 +103,62 @@ system.cpu.dtb.read_misses 0 # DT system.cpu.dtb.write_accesses 0 # DTB write accesses system.cpu.dtb.write_hits 0 # DTB write hits system.cpu.dtb.write_misses 0 # DTB write misses -system.cpu.icache.ReadReq_accesses 5658 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 55772.277228 # average ReadReq miss latency -system.cpu.icache.ReadReq_avg_mshr_miss_latency 52772.277228 # average ReadReq mshr miss latency -system.cpu.icache.ReadReq_hits 5355 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 16899000 # number of ReadReq miss cycles -system.cpu.icache.ReadReq_miss_rate 0.053552 # miss rate for ReadReq accesses -system.cpu.icache.ReadReq_misses 303 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_miss_latency 15990000 # number of ReadReq MSHR miss cycles -system.cpu.icache.ReadReq_mshr_miss_rate 0.053552 # mshr miss rate for ReadReq accesses -system.cpu.icache.ReadReq_mshr_misses 303 # number of ReadReq MSHR misses +system.cpu.icache.ReadReq_accesses 5687 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 55773.026316 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 52773.026316 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_hits 5383 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 16955000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.053455 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 304 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_miss_latency 16043000 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_rate 0.053455 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_misses 304 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.icache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.icache.avg_refs 17.673267 # Average number of references to valid blocks. +system.cpu.icache.avg_refs 17.707237 # Average number of references to valid blocks. system.cpu.icache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed -system.cpu.icache.demand_accesses 5658 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 55772.277228 # average overall miss latency -system.cpu.icache.demand_avg_mshr_miss_latency 52772.277228 # average overall mshr miss latency -system.cpu.icache.demand_hits 5355 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 16899000 # number of demand (read+write) miss cycles -system.cpu.icache.demand_miss_rate 0.053552 # miss rate for demand accesses -system.cpu.icache.demand_misses 303 # number of demand (read+write) misses +system.cpu.icache.demand_accesses 5687 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 55773.026316 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 52773.026316 # average overall mshr miss latency +system.cpu.icache.demand_hits 5383 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 16955000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.053455 # miss rate for demand accesses +system.cpu.icache.demand_misses 304 # number of demand (read+write) misses system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.icache.demand_mshr_miss_latency 15990000 # number of demand (read+write) MSHR miss cycles -system.cpu.icache.demand_mshr_miss_rate 0.053552 # mshr miss rate for demand accesses -system.cpu.icache.demand_mshr_misses 303 # number of demand (read+write) MSHR misses +system.cpu.icache.demand_mshr_miss_latency 16043000 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_rate 0.053455 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_misses 304 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.icache.overall_accesses 5658 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 55772.277228 # average overall miss latency -system.cpu.icache.overall_avg_mshr_miss_latency 52772.277228 # average overall mshr miss latency +system.cpu.icache.overall_accesses 5687 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 55773.026316 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 52773.026316 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.icache.overall_hits 5355 # number of overall hits -system.cpu.icache.overall_miss_latency 16899000 # number of overall miss cycles -system.cpu.icache.overall_miss_rate 0.053552 # miss rate for overall accesses -system.cpu.icache.overall_misses 303 # number of overall misses +system.cpu.icache.overall_hits 5383 # number of overall hits +system.cpu.icache.overall_miss_latency 16955000 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.053455 # miss rate for overall accesses +system.cpu.icache.overall_misses 304 # number of overall misses system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.icache.overall_mshr_miss_latency 15990000 # number of overall MSHR miss cycles -system.cpu.icache.overall_mshr_miss_rate 0.053552 # mshr miss rate for overall accesses -system.cpu.icache.overall_mshr_misses 303 # number of overall MSHR misses +system.cpu.icache.overall_mshr_miss_latency 16043000 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_rate 0.053455 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_misses 304 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.icache.replacements 13 # number of replacements -system.cpu.icache.sampled_refs 303 # Sample count of references to valid blocks. +system.cpu.icache.sampled_refs 304 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 135.958324 # Cycle average of tags in use -system.cpu.icache.total_refs 5355 # Total number of references to valid blocks. +system.cpu.icache.tagsinuse 136.385131 # Cycle average of tags in use +system.cpu.icache.total_refs 5383 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks -system.cpu.icache_port.instReqsProcessed 5657 # Number of Instructions Requests that completed in this resource. -system.cpu.ipc 0.096066 # IPC: Instructions Per Cycle (Per-Thread) -system.cpu.ipc_total 0.096066 # IPC: Total IPC of All Threads +system.cpu.icache_port.instReqsProcessed 5686 # Number of Instructions Requests that completed in this resource. +system.cpu.ipc 0.096284 # IPC: Instructions Per Cycle (Per-Thread) +system.cpu.ipc_total 0.096284 # IPC: Total IPC of All Threads system.cpu.itb.accesses 0 # DTB accesses system.cpu.itb.hits 0 # DTB hits system.cpu.itb.misses 0 # DTB misses @@ -177,16 +177,16 @@ system.cpu.l2cache.ReadExReq_misses 50 # nu system.cpu.l2cache.ReadExReq_mshr_miss_latency 2004000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses system.cpu.l2cache.ReadExReq_mshr_misses 50 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 385 # number of ReadReq accesses(hits+misses) -system.cpu.l2cache.ReadReq_avg_miss_latency 52052.219321 # average ReadReq miss latency -system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40026.109661 # average ReadReq mshr miss latency +system.cpu.l2cache.ReadReq_accesses 386 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 52052.083333 # average ReadReq miss latency +system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40026.041667 # average ReadReq mshr miss latency system.cpu.l2cache.ReadReq_hits 2 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 19936000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.994805 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 383 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 15330000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.994805 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 383 # number of ReadReq MSHR misses +system.cpu.l2cache.ReadReq_miss_latency 19988000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.994819 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 384 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 15370000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.994819 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 384 # number of ReadReq MSHR misses system.cpu.l2cache.UpgradeReq_accesses 14 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 52535.714286 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40071.428571 # average UpgradeReq mshr miss latency @@ -198,53 +198,53 @@ system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 system.cpu.l2cache.UpgradeReq_mshr_misses 14 # number of UpgradeReq MSHR misses system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 0.005420 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 0.005405 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 435 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 52103.926097 # average overall miss latency -system.cpu.l2cache.demand_avg_mshr_miss_latency 40032.332564 # average overall mshr miss latency +system.cpu.l2cache.demand_accesses 436 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 52103.686636 # average overall miss latency +system.cpu.l2cache.demand_avg_mshr_miss_latency 40032.258065 # average overall mshr miss latency system.cpu.l2cache.demand_hits 2 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 22561000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.995402 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 433 # number of demand (read+write) misses +system.cpu.l2cache.demand_miss_latency 22613000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.995413 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 434 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 17334000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.995402 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 433 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 17374000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.995413 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 434 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 435 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 52103.926097 # average overall miss latency -system.cpu.l2cache.overall_avg_mshr_miss_latency 40032.332564 # average overall mshr miss latency +system.cpu.l2cache.overall_accesses 436 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 52103.686636 # average overall miss latency +system.cpu.l2cache.overall_avg_mshr_miss_latency 40032.258065 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.l2cache.overall_hits 2 # number of overall hits -system.cpu.l2cache.overall_miss_latency 22561000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.995402 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 433 # number of overall misses +system.cpu.l2cache.overall_miss_latency 22613000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.995413 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 434 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 17334000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.995402 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 433 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 17374000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.995413 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 434 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.l2cache.replacements 0 # number of replacements -system.cpu.l2cache.sampled_refs 369 # Sample count of references to valid blocks. +system.cpu.l2cache.sampled_refs 370 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 183.249501 # Cycle average of tags in use +system.cpu.l2cache.tagsinuse 183.672228 # Cycle average of tags in use system.cpu.l2cache.total_refs 2 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.l2cache.writebacks 0 # number of writebacks -system.cpu.numCycles 58876 # number of cpu cycles simulated +system.cpu.numCycles 59044 # number of cpu cycles simulated system.cpu.smtCommittedInsts 0 # Number of SMT Instructions Simulated (Per-Thread) system.cpu.smtCycles 0 # Total number of cycles that the CPU was simultaneous multithreading.(SMT) system.cpu.smt_cpi no_value # CPI: Total SMT-CPI system.cpu.smt_ipc no_value # IPC: Total SMT-IPC -system.cpu.threadCycles 58876 # Total Number of Cycles A Thread Was Active in CPU (Per-Thread) +system.cpu.threadCycles 59044 # Total Number of Cycles A Thread Was Active in CPU (Per-Thread) system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/mips/linux/o3-timing/config.ini b/tests/quick/00.hello/ref/mips/linux/o3-timing/config.ini index 9e32dcc7f7..b3bdddcfee 100644 --- a/tests/quick/00.hello/ref/mips/linux/o3-timing/config.ini +++ b/tests/quick/00.hello/ref/mips/linux/o3-timing/config.ini @@ -412,7 +412,7 @@ egid=100 env= errout=cerr euid=100 -executable=/dist/m5/regression/test-progs/hello/bin/mips/linux/hello +executable=tests/test-progs/hello/bin/mips/linux/hello gid=100 input=cin max_stack_size=67108864 diff --git a/tests/quick/00.hello/ref/mips/linux/o3-timing/simout b/tests/quick/00.hello/ref/mips/linux/o3-timing/simout index 5aef74b1ce..9562c954fd 100755 --- a/tests/quick/00.hello/ref/mips/linux/o3-timing/simout +++ b/tests/quick/00.hello/ref/mips/linux/o3-timing/simout @@ -5,13 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Jul 6 2009 11:05:29 -M5 revision d3635cac686a 6289 default ruby_refs.diff qtip tip -M5 started Jul 6 2009 11:11:08 -M5 executing on maize +M5 compiled Sep 24 2009 12:19:09 +M5 revision 9bc3e4611009+ 6661+ default tip +M5 started Sep 24 2009 12:19:46 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/o3-timing -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/o3-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 13881500 because target called exit() +Exiting @ tick 13914500 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/o3-timing/stats.txt b/tests/quick/00.hello/ref/mips/linux/o3-timing/stats.txt index 6d8206a5c2..bdce7b5d39 100644 --- a/tests/quick/00.hello/ref/mips/linux/o3-timing/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/o3-timing/stats.txt @@ -1,65 +1,65 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 27478 # Simulator instruction rate (inst/s) -host_mem_usage 190884 # Number of bytes of host memory used -host_seconds 0.18 # Real time elapsed on the host -host_tick_rate 75816661 # Simulator tick rate (ticks/s) +host_inst_rate 59567 # Simulator instruction rate (inst/s) +host_mem_usage 155776 # Number of bytes of host memory used +host_seconds 0.09 # Real time elapsed on the host +host_tick_rate 163592222 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5024 # Number of instructions simulated +sim_insts 5049 # Number of instructions simulated sim_seconds 0.000014 # Number of seconds simulated -sim_ticks 13881500 # Number of ticks simulated +sim_ticks 13914500 # Number of ticks simulated system.cpu.BPredUnit.BTBCorrect 0 # Number of correct BTB predictions (this stat may not work properly. -system.cpu.BPredUnit.BTBHits 549 # Number of BTB hits -system.cpu.BPredUnit.BTBLookups 1924 # Number of BTB lookups +system.cpu.BPredUnit.BTBHits 552 # Number of BTB hits +system.cpu.BPredUnit.BTBLookups 1939 # Number of BTB lookups system.cpu.BPredUnit.RASInCorrect 53 # Number of incorrect RAS predictions. -system.cpu.BPredUnit.condIncorrect 721 # Number of conditional branches incorrect -system.cpu.BPredUnit.condPredicted 1540 # Number of conditional branches predicted -system.cpu.BPredUnit.lookups 2339 # Number of BP lookups -system.cpu.BPredUnit.usedRAS 384 # Number of times the RAS was used to get a target. -system.cpu.commit.COM:branches 879 # Number of branches committed +system.cpu.BPredUnit.condIncorrect 722 # Number of conditional branches incorrect +system.cpu.BPredUnit.condPredicted 1555 # Number of conditional branches predicted +system.cpu.BPredUnit.lookups 2357 # Number of BP lookups +system.cpu.BPredUnit.usedRAS 387 # Number of times the RAS was used to get a target. +system.cpu.commit.COM:branches 885 # Number of branches committed system.cpu.commit.COM:bw_lim_events 63 # number cycles where commit BW limit reached system.cpu.commit.COM:bw_limited 0 # number of insts not committed due to BW limits -system.cpu.commit.COM:committed_per_cycle::samples 14165 # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::mean 0.399223 # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::stdev 1.126414 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::samples 14230 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::mean 0.399438 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::stdev 1.125719 # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::underflows 0 0.00% 0.00% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::0-1 11701 82.61% 82.61% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::1-2 1166 8.23% 90.84% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::2-3 493 3.48% 94.32% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::3-4 279 1.97% 96.29% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::4-5 290 2.05% 98.33% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::5-6 74 0.52% 98.86% # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::6-7 61 0.43% 99.29% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::0-1 11753 82.59% 82.59% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::1-2 1168 8.21% 90.80% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::2-3 499 3.51% 94.31% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::3-4 284 2.00% 96.30% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::4-5 291 2.04% 98.35% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::5-6 72 0.51% 98.85% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::6-7 62 0.44% 99.29% # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::7-8 38 0.27% 99.56% # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::8 63 0.44% 100.00% # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::overflows 0 0.00% 100.00% # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::min_value 0 # Number of insts commited each cycle system.cpu.commit.COM:committed_per_cycle::max_value 8 # Number of insts commited each cycle -system.cpu.commit.COM:committed_per_cycle::total 14165 # Number of insts commited each cycle -system.cpu.commit.COM:count 5655 # Number of instructions committed -system.cpu.commit.COM:loads 1130 # Number of loads committed +system.cpu.commit.COM:committed_per_cycle::total 14230 # Number of insts commited each cycle +system.cpu.commit.COM:count 5684 # Number of instructions committed +system.cpu.commit.COM:loads 1133 # Number of loads committed system.cpu.commit.COM:membars 0 # Number of memory barriers committed -system.cpu.commit.COM:refs 2054 # Number of memory references committed +system.cpu.commit.COM:refs 2057 # Number of memory references committed system.cpu.commit.COM:swp_count 0 # Number of s/w prefetches committed -system.cpu.commit.branchMispredicts 604 # The number of times a branch was mispredicted -system.cpu.commit.commitCommittedInsts 5655 # The number of committed instructions +system.cpu.commit.branchMispredicts 605 # The number of times a branch was mispredicted +system.cpu.commit.commitCommittedInsts 5684 # The number of committed instructions system.cpu.commit.commitNonSpecStalls 15 # The number of times commit has been forced to stall to communicate backwards -system.cpu.commit.commitSquashedInsts 5936 # The number of squashed insts skipped by commit -system.cpu.committedInsts 5024 # Number of Instructions Simulated -system.cpu.committedInsts_total 5024 # Number of Instructions Simulated -system.cpu.cpi 5.526274 # CPI: Cycles Per Instruction -system.cpu.cpi_total 5.526274 # CPI: Total CPI of All Threads -system.cpu.dcache.ReadReq_accesses 2286 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 33976.377953 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 36034.883721 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 2159 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 4315000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.055556 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 127 # number of ReadReq misses +system.cpu.commit.commitSquashedInsts 5973 # The number of squashed insts skipped by commit +system.cpu.committedInsts 5049 # Number of Instructions Simulated +system.cpu.committedInsts_total 5049 # Number of Instructions Simulated +system.cpu.cpi 5.511983 # CPI: Cycles Per Instruction +system.cpu.cpi_total 5.511983 # CPI: Total CPI of All Threads +system.cpu.dcache.ReadReq_accesses 2297 # number of ReadReq accesses(hits+misses) +system.cpu.dcache.ReadReq_avg_miss_latency 34007.812500 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 36022.988506 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 2169 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 4353000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.055725 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 128 # number of ReadReq misses system.cpu.dcache.ReadReq_mshr_hits 41 # number of ReadReq MSHR hits -system.cpu.dcache.ReadReq_mshr_miss_latency 3099000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.037620 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 86 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_mshr_miss_latency 3134000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.037875 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 87 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 924 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 27701.724138 # average WriteReq miss latency system.cpu.dcache.WriteReq_avg_mshr_miss_latency 36093.750000 # average WriteReq mshr miss latency @@ -73,54 +73,54 @@ system.cpu.dcache.WriteReq_mshr_miss_rate 0.069264 # m system.cpu.dcache.WriteReq_mshr_misses 64 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 20.970370 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 20.889706 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed -system.cpu.dcache.demand_accesses 3210 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 29612.709832 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 36060 # average overall mshr miss latency -system.cpu.dcache.demand_hits 2793 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 12348500 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.129907 # miss rate for demand accesses -system.cpu.dcache.demand_misses 417 # number of demand (read+write) misses +system.cpu.dcache.demand_accesses 3221 # number of demand (read+write) accesses +system.cpu.dcache.demand_avg_miss_latency 29632.775120 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 36052.980132 # average overall mshr miss latency +system.cpu.dcache.demand_hits 2803 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 12386500 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.129773 # miss rate for demand accesses +system.cpu.dcache.demand_misses 418 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 267 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 5409000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.046729 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 150 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 5444000 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.046880 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 151 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.dcache.overall_accesses 3210 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 29612.709832 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 36060 # average overall mshr miss latency +system.cpu.dcache.overall_accesses 3221 # number of overall (read+write) accesses +system.cpu.dcache.overall_avg_miss_latency 29632.775120 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 36052.980132 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 2793 # number of overall hits -system.cpu.dcache.overall_miss_latency 12348500 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.129907 # miss rate for overall accesses -system.cpu.dcache.overall_misses 417 # number of overall misses +system.cpu.dcache.overall_hits 2803 # number of overall hits +system.cpu.dcache.overall_miss_latency 12386500 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.129773 # miss rate for overall accesses +system.cpu.dcache.overall_misses 418 # number of overall misses system.cpu.dcache.overall_mshr_hits 267 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 5409000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.046729 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 150 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 5444000 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.046880 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 151 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.dcache.replacements 0 # number of replacements -system.cpu.dcache.sampled_refs 135 # Sample count of references to valid blocks. +system.cpu.dcache.sampled_refs 136 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 87.531358 # Cycle average of tags in use -system.cpu.dcache.total_refs 2831 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 87.690614 # Cycle average of tags in use +system.cpu.dcache.total_refs 2841 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.dcache.writebacks 0 # number of writebacks system.cpu.decode.DECODE:BlockedCycles 479 # Number of cycles decode is blocked system.cpu.decode.DECODE:BranchMispred 128 # Number of times decode detected a branch misprediction system.cpu.decode.DECODE:BranchResolved 128 # Number of times decode resolved a branch -system.cpu.decode.DECODE:DecodedInsts 14141 # Number of instructions handled by decode -system.cpu.decode.DECODE:IdleCycles 9863 # Number of cycles decode is idle -system.cpu.decode.DECODE:RunCycles 3823 # Number of cycles decode is running -system.cpu.decode.DECODE:SquashCycles 1052 # Number of cycles decode is squashing +system.cpu.decode.DECODE:DecodedInsts 14211 # Number of instructions handled by decode +system.cpu.decode.DECODE:IdleCycles 9912 # Number of cycles decode is idle +system.cpu.decode.DECODE:RunCycles 3839 # Number of cycles decode is running +system.cpu.decode.DECODE:SquashCycles 1056 # Number of cycles decode is squashing system.cpu.decode.DECODE:SquashedInsts 251 # Number of squashed instructions handled by decode system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits @@ -131,116 +131,116 @@ system.cpu.dtb.read_misses 0 # DT system.cpu.dtb.write_accesses 0 # DTB write accesses system.cpu.dtb.write_hits 0 # DTB write hits system.cpu.dtb.write_misses 0 # DTB write misses -system.cpu.fetch.Branches 2339 # Number of branches that fetch encountered -system.cpu.fetch.CacheLines 2162 # Number of cache lines fetched -system.cpu.fetch.Cycles 6161 # Number of cycles fetch has run and was not squashing or blocked +system.cpu.fetch.Branches 2357 # Number of branches that fetch encountered +system.cpu.fetch.CacheLines 2171 # Number of cache lines fetched +system.cpu.fetch.Cycles 6187 # Number of cycles fetch has run and was not squashing or blocked system.cpu.fetch.IcacheSquashes 360 # Number of outstanding Icache misses that were squashed -system.cpu.fetch.Insts 15261 # Number of instructions fetch has processed -system.cpu.fetch.SquashCycles 737 # Number of cycles fetch has spent squashing -system.cpu.fetch.branchRate 0.084246 # Number of branch fetches per cycle -system.cpu.fetch.icacheStallCycles 2162 # Number of cycles fetch is stalled on an Icache miss -system.cpu.fetch.predictedBranches 933 # Number of branches that fetch has predicted taken -system.cpu.fetch.rate 0.549669 # Number of inst fetches per cycle -system.cpu.fetch.rateDist::samples 15217 # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::mean 1.002892 # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::stdev 2.262712 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.Insts 15337 # Number of instructions fetch has processed +system.cpu.fetch.SquashCycles 738 # Number of cycles fetch has spent squashing +system.cpu.fetch.branchRate 0.084693 # Number of branch fetches per cycle +system.cpu.fetch.icacheStallCycles 2171 # Number of cycles fetch is stalled on an Icache miss +system.cpu.fetch.predictedBranches 939 # Number of branches that fetch has predicted taken +system.cpu.fetch.rate 0.551096 # Number of inst fetches per cycle +system.cpu.fetch.rateDist::samples 15286 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::mean 1.003336 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::stdev 2.263199 # Number of instructions fetched each cycle (Total) system.cpu.fetch.rateDist::underflows 0 0.00% 0.00% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::0-1 11225 73.77% 73.77% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::1-2 1766 11.61% 85.37% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::2-3 196 1.29% 86.66% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::3-4 137 0.90% 87.56% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::4-5 314 2.06% 89.62% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::5-6 113 0.74% 90.37% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::6-7 304 2.00% 92.36% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::7-8 249 1.64% 94.00% # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::8 913 6.00% 100.00% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::0-1 11277 73.77% 73.77% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::1-2 1770 11.58% 85.35% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::2-3 198 1.30% 86.65% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::3-4 138 0.90% 87.55% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::4-5 316 2.07% 89.62% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::5-6 114 0.75% 90.36% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::6-7 306 2.00% 92.37% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::7-8 249 1.63% 93.99% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::8 918 6.01% 100.00% # Number of instructions fetched each cycle (Total) system.cpu.fetch.rateDist::overflows 0 0.00% 100.00% # Number of instructions fetched each cycle (Total) system.cpu.fetch.rateDist::min_value 0 # Number of instructions fetched each cycle (Total) system.cpu.fetch.rateDist::max_value 8 # Number of instructions fetched each cycle (Total) -system.cpu.fetch.rateDist::total 15217 # Number of instructions fetched each cycle (Total) -system.cpu.icache.ReadReq_accesses 2162 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 35500 # average ReadReq miss latency +system.cpu.fetch.rateDist::total 15286 # Number of instructions fetched each cycle (Total) +system.cpu.icache.ReadReq_accesses 2171 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 35436.489607 # average ReadReq miss latency system.cpu.icache.ReadReq_avg_mshr_miss_latency 34915.151515 # average ReadReq mshr miss latency -system.cpu.icache.ReadReq_hits 1731 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 15300500 # number of ReadReq miss cycles -system.cpu.icache.ReadReq_miss_rate 0.199352 # miss rate for ReadReq accesses -system.cpu.icache.ReadReq_misses 431 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_hits 101 # number of ReadReq MSHR hits +system.cpu.icache.ReadReq_hits 1738 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 15344000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.199447 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 433 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_hits 103 # number of ReadReq MSHR hits system.cpu.icache.ReadReq_mshr_miss_latency 11522000 # number of ReadReq MSHR miss cycles -system.cpu.icache.ReadReq_mshr_miss_rate 0.152636 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_miss_rate 0.152004 # mshr miss rate for ReadReq accesses system.cpu.icache.ReadReq_mshr_misses 330 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.icache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.icache.avg_refs 5.245455 # Average number of references to valid blocks. +system.cpu.icache.avg_refs 5.266667 # Average number of references to valid blocks. system.cpu.icache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed -system.cpu.icache.demand_accesses 2162 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 35500 # average overall miss latency +system.cpu.icache.demand_accesses 2171 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 35436.489607 # average overall miss latency system.cpu.icache.demand_avg_mshr_miss_latency 34915.151515 # average overall mshr miss latency -system.cpu.icache.demand_hits 1731 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 15300500 # number of demand (read+write) miss cycles -system.cpu.icache.demand_miss_rate 0.199352 # miss rate for demand accesses -system.cpu.icache.demand_misses 431 # number of demand (read+write) misses -system.cpu.icache.demand_mshr_hits 101 # number of demand (read+write) MSHR hits +system.cpu.icache.demand_hits 1738 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 15344000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.199447 # miss rate for demand accesses +system.cpu.icache.demand_misses 433 # number of demand (read+write) misses +system.cpu.icache.demand_mshr_hits 103 # number of demand (read+write) MSHR hits system.cpu.icache.demand_mshr_miss_latency 11522000 # number of demand (read+write) MSHR miss cycles -system.cpu.icache.demand_mshr_miss_rate 0.152636 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_miss_rate 0.152004 # mshr miss rate for demand accesses system.cpu.icache.demand_mshr_misses 330 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.icache.overall_accesses 2162 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 35500 # average overall miss latency +system.cpu.icache.overall_accesses 2171 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 35436.489607 # average overall miss latency system.cpu.icache.overall_avg_mshr_miss_latency 34915.151515 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.icache.overall_hits 1731 # number of overall hits -system.cpu.icache.overall_miss_latency 15300500 # number of overall miss cycles -system.cpu.icache.overall_miss_rate 0.199352 # miss rate for overall accesses -system.cpu.icache.overall_misses 431 # number of overall misses -system.cpu.icache.overall_mshr_hits 101 # number of overall MSHR hits +system.cpu.icache.overall_hits 1738 # number of overall hits +system.cpu.icache.overall_miss_latency 15344000 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.199447 # miss rate for overall accesses +system.cpu.icache.overall_misses 433 # number of overall misses +system.cpu.icache.overall_mshr_hits 103 # number of overall MSHR hits system.cpu.icache.overall_mshr_miss_latency 11522000 # number of overall MSHR miss cycles -system.cpu.icache.overall_mshr_miss_rate 0.152636 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_miss_rate 0.152004 # mshr miss rate for overall accesses system.cpu.icache.overall_mshr_misses 330 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.icache.replacements 16 # number of replacements system.cpu.icache.sampled_refs 330 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 158.760808 # Cycle average of tags in use -system.cpu.icache.total_refs 1731 # Total number of references to valid blocks. +system.cpu.icache.tagsinuse 159.086288 # Cycle average of tags in use +system.cpu.icache.total_refs 1738 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks -system.cpu.idleCycles 12547 # Total number of cycles that the CPU has spent unscheduled due to idling -system.cpu.iew.EXEC:branches 1206 # Number of branches executed -system.cpu.iew.EXEC:nop 1806 # number of nop insts executed -system.cpu.iew.EXEC:rate 0.291349 # Inst execution rate -system.cpu.iew.EXEC:refs 3420 # number of memory reference insts executed +system.cpu.idleCycles 12544 # Total number of cycles that the CPU has spent unscheduled due to idling +system.cpu.iew.EXEC:branches 1216 # Number of branches executed +system.cpu.iew.EXEC:nop 1820 # number of nop insts executed +system.cpu.iew.EXEC:rate 0.292239 # Inst execution rate +system.cpu.iew.EXEC:refs 3432 # number of memory reference insts executed system.cpu.iew.EXEC:stores 1048 # Number of stores executed system.cpu.iew.EXEC:swp 0 # number of swp insts executed -system.cpu.iew.WB:consumers 4016 # num instructions consuming a value -system.cpu.iew.WB:count 7315 # cumulative count of insts written-back -system.cpu.iew.WB:fanout 0.694970 # average fanout of values written-back +system.cpu.iew.WB:consumers 4040 # num instructions consuming a value +system.cpu.iew.WB:count 7355 # cumulative count of insts written-back +system.cpu.iew.WB:fanout 0.694802 # average fanout of values written-back system.cpu.iew.WB:penalized 0 # number of instrctions required to write to 'other' IQ system.cpu.iew.WB:penalized_rate 0 # fraction of instructions written-back that wrote to 'other' IQ -system.cpu.iew.WB:producers 2791 # num instructions producing a value -system.cpu.iew.WB:rate 0.263471 # insts written-back per cycle -system.cpu.iew.WB:sent 7402 # cumulative count of insts sent to commit -system.cpu.iew.branchMispredicts 661 # Number of branch mispredicts detected at execute +system.cpu.iew.WB:producers 2807 # num instructions producing a value +system.cpu.iew.WB:rate 0.264283 # insts written-back per cycle +system.cpu.iew.WB:sent 7444 # cumulative count of insts sent to commit +system.cpu.iew.branchMispredicts 663 # Number of branch mispredicts detected at execute system.cpu.iew.iewBlockCycles 8 # Number of cycles IEW is blocking -system.cpu.iew.iewDispLoadInsts 2783 # Number of dispatched load instructions +system.cpu.iew.iewDispLoadInsts 2795 # Number of dispatched load instructions system.cpu.iew.iewDispNonSpecInsts 15 # Number of dispatched non-speculative instructions system.cpu.iew.iewDispSquashedInsts 968 # Number of squashed instructions skipped by dispatch system.cpu.iew.iewDispStoreInsts 1158 # Number of dispatched store instructions -system.cpu.iew.iewDispatchedInsts 11594 # Number of instructions dispatched to IQ -system.cpu.iew.iewExecLoadInsts 2372 # Number of load instructions executed +system.cpu.iew.iewDispatchedInsts 11660 # Number of instructions dispatched to IQ +system.cpu.iew.iewExecLoadInsts 2384 # Number of load instructions executed system.cpu.iew.iewExecSquashedInsts 531 # Number of squashed instructions skipped in execute -system.cpu.iew.iewExecutedInsts 8089 # Number of executed instructions +system.cpu.iew.iewExecutedInsts 8133 # Number of executed instructions system.cpu.iew.iewIQFullEvents 0 # Number of times the IQ has become full, causing a stall system.cpu.iew.iewIdleCycles 0 # Number of cycles IEW is idle system.cpu.iew.iewLSQFullEvents 1 # Number of times the LSQ has become full, causing a stall -system.cpu.iew.iewSquashCycles 1052 # Number of cycles IEW is squashing +system.cpu.iew.iewSquashCycles 1056 # Number of cycles IEW is squashing system.cpu.iew.iewUnblockCycles 0 # Number of cycles IEW is unblocking system.cpu.iew.lsq.thread.0.blockedLoads 0 # Number of blocked loads due to partial load-store forwarding system.cpu.iew.lsq.thread.0.cacheBlocked 0 # Number of times an access to memory failed due to the cache being blocked @@ -250,30 +250,30 @@ system.cpu.iew.lsq.thread.0.invAddrLoads 0 # Nu system.cpu.iew.lsq.thread.0.invAddrSwpfs 0 # Number of software prefetches ignored due to an invalid address system.cpu.iew.lsq.thread.0.memOrderViolation 22 # Number of memory ordering violations system.cpu.iew.lsq.thread.0.rescheduledLoads 0 # Number of loads that were rescheduled -system.cpu.iew.lsq.thread.0.squashedLoads 1653 # Number of loads squashed +system.cpu.iew.lsq.thread.0.squashedLoads 1662 # Number of loads squashed system.cpu.iew.lsq.thread.0.squashedStores 234 # Number of stores squashed system.cpu.iew.memOrderViolationEvents 22 # Number of memory order violations -system.cpu.iew.predictedNotTakenIncorrect 276 # Number of branches that were predicted not taken incorrectly -system.cpu.iew.predictedTakenIncorrect 385 # Number of branches that were predicted taken incorrectly -system.cpu.ipc 0.180954 # IPC: Instructions Per Cycle -system.cpu.ipc_total 0.180954 # IPC: Total IPC of All Threads +system.cpu.iew.predictedNotTakenIncorrect 277 # Number of branches that were predicted not taken incorrectly +system.cpu.iew.predictedTakenIncorrect 386 # Number of branches that were predicted taken incorrectly +system.cpu.ipc 0.181423 # IPC: Instructions Per Cycle +system.cpu.ipc_total 0.181423 # IPC: Total IPC of All Threads system.cpu.iq.ISSUE:FU_type_0::No_OpClass 0 0.00% 0.00% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::IntAlu 4988 57.87% 57.87% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::IntMult 5 0.06% 57.92% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::IntDiv 2 0.02% 57.95% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatAdd 2 0.02% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatCmp 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatCvt 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatMult 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatDiv 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::FloatSqrt 0 0.00% 57.97% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::MemRead 2560 29.70% 87.67% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::MemWrite 1063 12.33% 100.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntAlu 5020 57.94% 57.94% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntMult 5 0.06% 58.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntDiv 2 0.02% 58.02% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatAdd 2 0.02% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatCmp 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatCvt 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatMult 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatDiv 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatSqrt 0 0.00% 58.04% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::MemRead 2572 29.69% 87.73% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::MemWrite 1063 12.27% 100.00% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::IprAccess 0 0.00% 100.00% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::InstPrefetch 0 0.00% 100.00% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::total 8620 # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::total 8664 # Type of FU issued system.cpu.iq.ISSUE:fu_busy_cnt 162 # FU busy when requested -system.cpu.iq.ISSUE:fu_busy_rate 0.018794 # FU busy rate (busy events/executed inst) +system.cpu.iq.ISSUE:fu_busy_rate 0.018698 # FU busy rate (busy events/executed inst) system.cpu.iq.ISSUE:fu_full::No_OpClass 0 0.00% 0.00% # attempts to use FU when none available system.cpu.iq.ISSUE:fu_full::IntAlu 10 6.17% 6.17% # attempts to use FU when none available system.cpu.iq.ISSUE:fu_full::IntMult 0 0.00% 6.17% # attempts to use FU when none available @@ -288,30 +288,30 @@ system.cpu.iq.ISSUE:fu_full::MemRead 98 60.49% 66.67% # at system.cpu.iq.ISSUE:fu_full::MemWrite 54 33.33% 100.00% # attempts to use FU when none available system.cpu.iq.ISSUE:fu_full::IprAccess 0 0.00% 100.00% # attempts to use FU when none available system.cpu.iq.ISSUE:fu_full::InstPrefetch 0 0.00% 100.00% # attempts to use FU when none available -system.cpu.iq.ISSUE:issued_per_cycle::samples 15217 # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::mean 0.566472 # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::stdev 1.217507 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::samples 15286 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::mean 0.566793 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::stdev 1.217668 # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::underflows 0 0.00% 0.00% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::0-1 11370 74.72% 74.72% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::1-2 1673 10.99% 85.71% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::2-3 787 5.17% 90.89% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::3-4 717 4.71% 95.60% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::4-5 332 2.18% 97.78% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::5-6 198 1.30% 99.08% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::0-1 11421 74.72% 74.72% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::1-2 1678 10.98% 85.69% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::2-3 792 5.18% 90.87% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::3-4 722 4.72% 95.60% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::4-5 333 2.18% 97.78% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::5-6 200 1.31% 99.08% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::6-7 91 0.60% 99.68% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::7-8 34 0.22% 99.90% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::8 15 0.10% 100.00% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::overflows 0 0.00% 100.00% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::min_value 0 # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::max_value 8 # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::total 15217 # Number of insts issued each cycle -system.cpu.iq.ISSUE:rate 0.310474 # Inst issue rate -system.cpu.iq.iqInstsAdded 9773 # Number of instructions added to the IQ (excludes non-spec) -system.cpu.iq.iqInstsIssued 8620 # Number of instructions issued +system.cpu.iq.ISSUE:issued_per_cycle::total 15286 # Number of insts issued each cycle +system.cpu.iq.ISSUE:rate 0.311319 # Inst issue rate +system.cpu.iq.iqInstsAdded 9825 # Number of instructions added to the IQ (excludes non-spec) +system.cpu.iq.iqInstsIssued 8664 # Number of instructions issued system.cpu.iq.iqNonSpecInstsAdded 15 # Number of non-speculative instructions added to the IQ -system.cpu.iq.iqSquashedInstsExamined 4182 # Number of squashed instructions iterated over during squash; mainly for profiling +system.cpu.iq.iqSquashedInstsExamined 4207 # Number of squashed instructions iterated over during squash; mainly for profiling system.cpu.iq.iqSquashedInstsIssued 30 # Number of squashed instructions issued -system.cpu.iq.iqSquashedOperandsExamined 2741 # Number of squashed operands that are examined and possibly removed from graph +system.cpu.iq.iqSquashedOperandsExamined 2761 # Number of squashed operands that are examined and possibly removed from graph system.cpu.itb.accesses 0 # DTB accesses system.cpu.itb.hits 0 # DTB hits system.cpu.itb.misses 0 # DTB misses @@ -330,16 +330,16 @@ system.cpu.l2cache.ReadExReq_misses 49 # nu system.cpu.l2cache.ReadExReq_mshr_miss_latency 1539000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses system.cpu.l2cache.ReadExReq_mshr_misses 49 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 416 # number of ReadReq accesses(hits+misses) -system.cpu.l2cache.ReadReq_avg_miss_latency 34308.252427 # average ReadReq miss latency -system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 31129.854369 # average ReadReq mshr miss latency +system.cpu.l2cache.ReadReq_accesses 417 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 34307.506053 # average ReadReq miss latency +system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 31130.750605 # average ReadReq mshr miss latency system.cpu.l2cache.ReadReq_hits 4 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 14135000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.990385 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 412 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 12825500 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.990385 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 412 # number of ReadReq MSHR misses +system.cpu.l2cache.ReadReq_miss_latency 14169000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.990408 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 413 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 12857000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.990408 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 413 # number of ReadReq MSHR misses system.cpu.l2cache.UpgradeReq_accesses 15 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 34400 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 31166.666667 # average UpgradeReq mshr miss latency @@ -351,68 +351,68 @@ system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 system.cpu.l2cache.UpgradeReq_mshr_misses 15 # number of UpgradeReq MSHR misses system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 0.010076 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 0.010050 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 465 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 34350.325380 # average overall miss latency -system.cpu.l2cache.demand_avg_mshr_miss_latency 31159.436009 # average overall mshr miss latency +system.cpu.l2cache.demand_accesses 466 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 34349.567100 # average overall miss latency +system.cpu.l2cache.demand_avg_mshr_miss_latency 31160.173160 # average overall mshr miss latency system.cpu.l2cache.demand_hits 4 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 15835500 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.991398 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 461 # number of demand (read+write) misses +system.cpu.l2cache.demand_miss_latency 15869500 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.991416 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 462 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 14364500 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.991398 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 461 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 14396000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.991416 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 462 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 465 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 34350.325380 # average overall miss latency -system.cpu.l2cache.overall_avg_mshr_miss_latency 31159.436009 # average overall mshr miss latency +system.cpu.l2cache.overall_accesses 466 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 34349.567100 # average overall miss latency +system.cpu.l2cache.overall_avg_mshr_miss_latency 31160.173160 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.l2cache.overall_hits 4 # number of overall hits -system.cpu.l2cache.overall_miss_latency 15835500 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.991398 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 461 # number of overall misses +system.cpu.l2cache.overall_miss_latency 15869500 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.991416 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 462 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 14364500 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.991398 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 461 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 14396000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.991416 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 462 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.l2cache.replacements 0 # number of replacements -system.cpu.l2cache.sampled_refs 397 # Sample count of references to valid blocks. +system.cpu.l2cache.sampled_refs 398 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 208.689672 # Cycle average of tags in use +system.cpu.l2cache.tagsinuse 209.158769 # Cycle average of tags in use system.cpu.l2cache.total_refs 4 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.l2cache.writebacks 0 # number of writebacks system.cpu.memDep0.conflictingLoads 5 # Number of conflicting loads. system.cpu.memDep0.conflictingStores 2 # Number of conflicting stores. -system.cpu.memDep0.insertedLoads 2783 # Number of loads inserted to the mem dependence unit. +system.cpu.memDep0.insertedLoads 2795 # Number of loads inserted to the mem dependence unit. system.cpu.memDep0.insertedStores 1158 # Number of stores inserted to the mem dependence unit. -system.cpu.numCycles 27764 # number of cpu cycles simulated +system.cpu.numCycles 27830 # number of cpu cycles simulated system.cpu.rename.RENAME:BlockCycles 20 # Number of cycles rename is blocking -system.cpu.rename.RENAME:CommittedMaps 3304 # Number of HB maps that are committed -system.cpu.rename.RENAME:IdleCycles 10242 # Number of cycles rename is idle +system.cpu.rename.RENAME:CommittedMaps 3323 # Number of HB maps that are committed +system.cpu.rename.RENAME:IdleCycles 10291 # Number of cycles rename is idle system.cpu.rename.RENAME:LSQFullEvents 16 # Number of times rename has blocked due to LSQ full -system.cpu.rename.RENAME:RenameLookups 15583 # Number of register rename lookups that rename has made -system.cpu.rename.RENAME:RenamedInsts 13384 # Number of instructions processed by rename -system.cpu.rename.RENAME:RenamedOperands 8214 # Number of destination operands rename has renamed -system.cpu.rename.RENAME:RunCycles 3446 # Number of cycles rename is running -system.cpu.rename.RENAME:SquashCycles 1052 # Number of cycles rename is squashing +system.cpu.rename.RENAME:RenameLookups 15666 # Number of register rename lookups that rename has made +system.cpu.rename.RENAME:RenamedInsts 13454 # Number of instructions processed by rename +system.cpu.rename.RENAME:RenamedOperands 8251 # Number of destination operands rename has renamed +system.cpu.rename.RENAME:RunCycles 3462 # Number of cycles rename is running +system.cpu.rename.RENAME:SquashCycles 1056 # Number of cycles rename is squashing system.cpu.rename.RENAME:UnblockCycles 29 # Number of cycles rename is unblocking -system.cpu.rename.RENAME:UndoneMaps 4910 # Number of HB maps that are undone due to squashing +system.cpu.rename.RENAME:UndoneMaps 4928 # Number of HB maps that are undone due to squashing system.cpu.rename.RENAME:serializeStallCycles 428 # count of cycles rename stalled for serializing inst system.cpu.rename.RENAME:serializingInsts 20 # count of serializing insts renamed system.cpu.rename.RENAME:skidInsts 125 # count of insts added to the skid buffer system.cpu.rename.RENAME:tempSerializingInsts 14 # count of temporary serializing insts renamed -system.cpu.timesIdled 249 # Number of times that the entire CPU went into an idle state and unscheduled itself +system.cpu.timesIdled 250 # Number of times that the entire CPU went into an idle state and unscheduled itself system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic/config.ini b/tests/quick/00.hello/ref/mips/linux/simple-atomic/config.ini index 5d677c7434..2961715307 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic/config.ini +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic/config.ini @@ -111,7 +111,7 @@ egid=100 env= errout=cerr euid=100 -executable=/dist/m5/regression/test-progs/hello/bin/mips/linux/hello +executable=tests/test-progs/hello/bin/mips/linux/hello gid=100 input=cin max_stack_size=67108864 diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic/simout b/tests/quick/00.hello/ref/mips/linux/simple-atomic/simout index b140ca5f45..77cc5d3215 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic/simout +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic/simout @@ -5,13 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Apr 21 2009 18:01:16 -M5 revision e6dd09514462 6117 default qtip tip stats-update -M5 started Apr 21 2009 18:01:42 -M5 executing on zizzer +M5 compiled Sep 24 2009 12:19:09 +M5 revision 9bc3e4611009+ 6661+ default tip +M5 started Sep 24 2009 12:19:47 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-atomic -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-atomic Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 2828000 because target called exit() +Exiting @ tick 2842500 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic/stats.txt b/tests/quick/00.hello/ref/mips/linux/simple-atomic/stats.txt index 60efc35e16..d36fc469a7 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic/stats.txt @@ -1,13 +1,13 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 525065 # Simulator instruction rate (inst/s) -host_mem_usage 193736 # Number of bytes of host memory used +host_inst_rate 588083 # Simulator instruction rate (inst/s) +host_mem_usage 149516 # Number of bytes of host memory used host_seconds 0.01 # Real time elapsed on the host -host_tick_rate 257090909 # Simulator tick rate (ticks/s) +host_tick_rate 285563593 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated +sim_insts 5685 # Number of instructions simulated sim_seconds 0.000003 # Number of seconds simulated -sim_ticks 2828000 # Number of ticks simulated +sim_ticks 2842500 # Number of ticks simulated system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits system.cpu.dtb.misses 0 # DTB misses @@ -28,9 +28,9 @@ system.cpu.itb.write_accesses 0 # DT system.cpu.itb.write_hits 0 # DTB write hits system.cpu.itb.write_misses 0 # DTB write misses system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 5657 # number of cpu cycles simulated -system.cpu.num_insts 5656 # Number of instructions executed -system.cpu.num_refs 2055 # Number of memory references +system.cpu.numCycles 5686 # number of cpu cycles simulated +system.cpu.num_insts 5685 # Number of instructions executed +system.cpu.num_refs 2058 # Number of memory references system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing/config.ini b/tests/quick/00.hello/ref/mips/linux/simple-timing/config.ini index 9f3729e929..2edca998b7 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing/config.ini +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing/config.ini @@ -211,7 +211,7 @@ egid=100 env= errout=cerr euid=100 -executable=/dist/m5/regression/test-progs/hello/bin/mips/linux/hello +executable=tests/test-progs/hello/bin/mips/linux/hello gid=100 input=cin max_stack_size=67108864 diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing/simout b/tests/quick/00.hello/ref/mips/linux/simple-timing/simout index 7d691a50ec..15331f6337 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing/simout +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing/simout @@ -5,13 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Apr 22 2009 06:58:36 -M5 revision ce26a627c841 6126 default qtip tip stats_no_compat.diff -M5 started Apr 22 2009 07:19:48 -M5 executing on maize +M5 compiled Sep 24 2009 12:19:09 +M5 revision 9bc3e4611009+ 6661+ default tip +M5 started Sep 24 2009 12:19:31 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-timing -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 32322000 because target called exit() +Exiting @ tick 32409000 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing/stats.txt b/tests/quick/00.hello/ref/mips/linux/simple-timing/stats.txt index 8e4a1aeedd..3bfaf35407 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing/stats.txt @@ -1,22 +1,22 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 198393 # Simulator instruction rate (inst/s) -host_mem_usage 202876 # Number of bytes of host memory used -host_seconds 0.03 # Real time elapsed on the host -host_tick_rate 1123305762 # Simulator tick rate (ticks/s) +host_inst_rate 303832 # Simulator instruction rate (inst/s) +host_mem_usage 155376 # Number of bytes of host memory used +host_seconds 0.02 # Real time elapsed on the host +host_tick_rate 1703674499 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated +sim_insts 5685 # Number of instructions simulated sim_seconds 0.000032 # Number of seconds simulated -sim_ticks 32322000 # Number of ticks simulated -system.cpu.dcache.ReadReq_accesses 1130 # number of ReadReq accesses(hits+misses) +sim_ticks 32409000 # Number of ticks simulated +system.cpu.dcache.ReadReq_accesses 1133 # number of ReadReq accesses(hits+misses) system.cpu.dcache.ReadReq_avg_miss_latency 56000 # average ReadReq miss latency system.cpu.dcache.ReadReq_avg_mshr_miss_latency 53000 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 1048 # number of ReadReq hits +system.cpu.dcache.ReadReq_hits 1051 # number of ReadReq hits system.cpu.dcache.ReadReq_miss_latency 4592000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.072566 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_miss_rate 0.072374 # miss rate for ReadReq accesses system.cpu.dcache.ReadReq_misses 82 # number of ReadReq misses system.cpu.dcache.ReadReq_mshr_miss_latency 4346000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.072566 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_miss_rate 0.072374 # mshr miss rate for ReadReq accesses system.cpu.dcache.ReadReq_mshr_misses 82 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 924 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 56000 # average WriteReq miss latency @@ -30,45 +30,45 @@ system.cpu.dcache.WriteReq_mshr_miss_rate 0.069264 # m system.cpu.dcache.WriteReq_mshr_misses 64 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 14.560606 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 14.583333 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed -system.cpu.dcache.demand_accesses 2054 # number of demand (read+write) accesses +system.cpu.dcache.demand_accesses 2057 # number of demand (read+write) accesses system.cpu.dcache.demand_avg_miss_latency 56000 # average overall miss latency system.cpu.dcache.demand_avg_mshr_miss_latency 53000 # average overall mshr miss latency -system.cpu.dcache.demand_hits 1908 # number of demand (read+write) hits +system.cpu.dcache.demand_hits 1911 # number of demand (read+write) hits system.cpu.dcache.demand_miss_latency 8176000 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.071081 # miss rate for demand accesses +system.cpu.dcache.demand_miss_rate 0.070977 # miss rate for demand accesses system.cpu.dcache.demand_misses 146 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits system.cpu.dcache.demand_mshr_miss_latency 7738000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.071081 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_miss_rate 0.070977 # mshr miss rate for demand accesses system.cpu.dcache.demand_mshr_misses 146 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.dcache.overall_accesses 2054 # number of overall (read+write) accesses +system.cpu.dcache.overall_accesses 2057 # number of overall (read+write) accesses system.cpu.dcache.overall_avg_miss_latency 56000 # average overall miss latency system.cpu.dcache.overall_avg_mshr_miss_latency 53000 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 1908 # number of overall hits +system.cpu.dcache.overall_hits 1911 # number of overall hits system.cpu.dcache.overall_miss_latency 8176000 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.071081 # miss rate for overall accesses +system.cpu.dcache.overall_miss_rate 0.070977 # miss rate for overall accesses system.cpu.dcache.overall_misses 146 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits system.cpu.dcache.overall_mshr_miss_latency 7738000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.071081 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_miss_rate 0.070977 # mshr miss rate for overall accesses system.cpu.dcache.overall_mshr_misses 146 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.dcache.replacements 0 # number of replacements system.cpu.dcache.sampled_refs 132 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 83.826869 # Cycle average of tags in use -system.cpu.dcache.total_refs 1922 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 83.830110 # Cycle average of tags in use +system.cpu.dcache.total_refs 1925 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.dcache.writebacks 0 # number of writebacks system.cpu.dtb.accesses 0 # DTB accesses @@ -80,57 +80,57 @@ system.cpu.dtb.read_misses 0 # DT system.cpu.dtb.write_accesses 0 # DTB write accesses system.cpu.dtb.write_hits 0 # DTB write hits system.cpu.dtb.write_misses 0 # DTB write misses -system.cpu.icache.ReadReq_accesses 5658 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 55722.772277 # average ReadReq miss latency -system.cpu.icache.ReadReq_avg_mshr_miss_latency 52722.772277 # average ReadReq mshr miss latency -system.cpu.icache.ReadReq_hits 5355 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 16884000 # number of ReadReq miss cycles -system.cpu.icache.ReadReq_miss_rate 0.053552 # miss rate for ReadReq accesses -system.cpu.icache.ReadReq_misses 303 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_miss_latency 15975000 # number of ReadReq MSHR miss cycles -system.cpu.icache.ReadReq_mshr_miss_rate 0.053552 # mshr miss rate for ReadReq accesses -system.cpu.icache.ReadReq_mshr_misses 303 # number of ReadReq MSHR misses +system.cpu.icache.ReadReq_accesses 5687 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 55723.684211 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 52723.684211 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_hits 5383 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 16940000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.053455 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 304 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_miss_latency 16028000 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_rate 0.053455 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_misses 304 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.icache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.icache.avg_refs 17.673267 # Average number of references to valid blocks. +system.cpu.icache.avg_refs 17.707237 # Average number of references to valid blocks. system.cpu.icache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed -system.cpu.icache.demand_accesses 5658 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 55722.772277 # average overall miss latency -system.cpu.icache.demand_avg_mshr_miss_latency 52722.772277 # average overall mshr miss latency -system.cpu.icache.demand_hits 5355 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 16884000 # number of demand (read+write) miss cycles -system.cpu.icache.demand_miss_rate 0.053552 # miss rate for demand accesses -system.cpu.icache.demand_misses 303 # number of demand (read+write) misses +system.cpu.icache.demand_accesses 5687 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 55723.684211 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 52723.684211 # average overall mshr miss latency +system.cpu.icache.demand_hits 5383 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 16940000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.053455 # miss rate for demand accesses +system.cpu.icache.demand_misses 304 # number of demand (read+write) misses system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.icache.demand_mshr_miss_latency 15975000 # number of demand (read+write) MSHR miss cycles -system.cpu.icache.demand_mshr_miss_rate 0.053552 # mshr miss rate for demand accesses -system.cpu.icache.demand_mshr_misses 303 # number of demand (read+write) MSHR misses +system.cpu.icache.demand_mshr_miss_latency 16028000 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_rate 0.053455 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_misses 304 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.icache.overall_accesses 5658 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 55722.772277 # average overall miss latency -system.cpu.icache.overall_avg_mshr_miss_latency 52722.772277 # average overall mshr miss latency +system.cpu.icache.overall_accesses 5687 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 55723.684211 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 52723.684211 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.icache.overall_hits 5355 # number of overall hits -system.cpu.icache.overall_miss_latency 16884000 # number of overall miss cycles -system.cpu.icache.overall_miss_rate 0.053552 # miss rate for overall accesses -system.cpu.icache.overall_misses 303 # number of overall misses +system.cpu.icache.overall_hits 5383 # number of overall hits +system.cpu.icache.overall_miss_latency 16940000 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.053455 # miss rate for overall accesses +system.cpu.icache.overall_misses 304 # number of overall misses system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.icache.overall_mshr_miss_latency 15975000 # number of overall MSHR miss cycles -system.cpu.icache.overall_mshr_miss_rate 0.053552 # mshr miss rate for overall accesses -system.cpu.icache.overall_mshr_misses 303 # number of overall MSHR misses +system.cpu.icache.overall_mshr_miss_latency 16028000 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_rate 0.053455 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_misses 304 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.icache.replacements 13 # number of replacements -system.cpu.icache.sampled_refs 303 # Sample count of references to valid blocks. +system.cpu.icache.sampled_refs 304 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 134.976151 # Cycle average of tags in use -system.cpu.icache.total_refs 5355 # Total number of references to valid blocks. +system.cpu.icache.tagsinuse 135.394401 # Cycle average of tags in use +system.cpu.icache.total_refs 5383 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles @@ -152,16 +152,16 @@ system.cpu.l2cache.ReadExReq_misses 50 # nu system.cpu.l2cache.ReadExReq_mshr_miss_latency 2000000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses system.cpu.l2cache.ReadExReq_mshr_misses 50 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 385 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_accesses 386 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency system.cpu.l2cache.ReadReq_hits 2 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 19916000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.994805 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 383 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 15320000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.994805 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 383 # number of ReadReq MSHR misses +system.cpu.l2cache.ReadReq_miss_latency 19968000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.994819 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 384 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 15360000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.994819 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 384 # number of ReadReq MSHR misses system.cpu.l2cache.UpgradeReq_accesses 14 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 52000 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency @@ -173,51 +173,51 @@ system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 system.cpu.l2cache.UpgradeReq_mshr_misses 14 # number of UpgradeReq MSHR misses system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 0.005420 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 0.005405 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 435 # number of demand (read+write) accesses +system.cpu.l2cache.demand_accesses 436 # number of demand (read+write) accesses system.cpu.l2cache.demand_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.demand_hits 2 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 22516000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.995402 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 433 # number of demand (read+write) misses +system.cpu.l2cache.demand_miss_latency 22568000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.995413 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 434 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 17320000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.995402 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 433 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 17360000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.995413 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 434 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 435 # number of overall (read+write) accesses +system.cpu.l2cache.overall_accesses 436 # number of overall (read+write) accesses system.cpu.l2cache.overall_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.l2cache.overall_hits 2 # number of overall hits -system.cpu.l2cache.overall_miss_latency 22516000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.995402 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 433 # number of overall misses +system.cpu.l2cache.overall_miss_latency 22568000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.995413 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 434 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 17320000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.995402 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 433 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 17360000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.995413 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 434 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.l2cache.replacements 0 # number of replacements -system.cpu.l2cache.sampled_refs 369 # Sample count of references to valid blocks. +system.cpu.l2cache.sampled_refs 370 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 181.998644 # Cycle average of tags in use +system.cpu.l2cache.tagsinuse 182.412916 # Cycle average of tags in use system.cpu.l2cache.total_refs 2 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.l2cache.writebacks 0 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 64644 # number of cpu cycles simulated -system.cpu.num_insts 5656 # Number of instructions executed -system.cpu.num_refs 2055 # Number of memory references +system.cpu.numCycles 64818 # number of cpu cycles simulated +system.cpu.num_insts 5685 # Number of instructions executed +system.cpu.num_refs 2058 # Number of memory references system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- From 25d1f2728ad848272d572bb5829f8df35594f783 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 25 Sep 2009 11:18:55 -0400 Subject: [PATCH 028/160] inorder-debug: fix cpu tick debug message --- src/cpu/inorder/cpu.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 486edc87b7..969359fae8 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -435,7 +435,7 @@ InOrderCPU::tick() //Tick next_tick = curTick + cycles(1); //tickEvent.schedule(next_tick); mainEventQueue.schedule(&tickEvent, nextCycle(curTick + 1)); - DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", nextCycle() + curTick); + DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", nextCycle(curTick + 1)); } } From f28ea7a6c9ea9506524adff0f468d6dd789c510c Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 26 Sep 2009 10:50:50 -0700 Subject: [PATCH 029/160] O3: Mark fetch stage as active if it faults. Otherwise if the rest of the pipeline is idle then fault will never propagate to commit to be handled, causing CPU to deadlock. --- src/cpu/o3/fetch_impl.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 5c6e287dcb..e6815ef8aa 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1264,6 +1264,8 @@ DefaultFetch::fetch(bool &status_change) toDecode->insts[numInst] = instruction; toDecode->size++; + wroteToTimeBuffer = true; + DPRINTF(Fetch, "[tid:%i]: Blocked, need to handle the trap.\n",tid); fetchStatus[tid] = TrapPending; From 72cfed41641bbea2ea3dc78958ed3b1e2c27bbf9 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 26 Sep 2009 10:50:50 -0700 Subject: [PATCH 030/160] Force prefetches to check cache and MSHRs immediately prior to issue. This prevents redundant prefetches from being issued, solving the occasional 'needsExclusive && !blk->isWritable()' assertion failure in cache_impl.hh that several people have run into. Eliminates "prefetch_cache_check_push" flag, neither setting of which really solved the problem. --- src/mem/cache/BaseCache.py | 2 -- src/mem/cache/cache_impl.hh | 13 ++++++++----- src/mem/cache/prefetch/base.cc | 16 ---------------- src/mem/cache/prefetch/base.hh | 4 ---- 4 files changed, 8 insertions(+), 27 deletions(-) diff --git a/src/mem/cache/BaseCache.py b/src/mem/cache/BaseCache.py index bdef07cb4d..5ded054008 100644 --- a/src/mem/cache/BaseCache.py +++ b/src/mem/cache/BaseCache.py @@ -68,8 +68,6 @@ class BaseCache(MemObject): "Latency of the prefetcher") prefetch_policy = Param.Prefetch('none', "Type of prefetcher to use") - prefetch_cache_check_push = Param.Bool(True, - "Check if in cache on push or pop of prefetch queue") prefetch_use_cpu_id = Param.Bool(True, "Use the CPU ID to separate calculations of prefetches") prefetch_data_accesses_only = Param.Bool(False, diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 80b7c545cc..d8630c1f5d 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1301,11 +1301,14 @@ Cache::getNextMSHR() // If we have a miss queue slot, we can try a prefetch PacketPtr pkt = prefetcher->getPacket(); if (pkt) { - // Update statistic on number of prefetches issued - // (hwpf_mshr_misses) - mshr_misses[pkt->cmdToIndex()][0/*pkt->req->threadId()*/]++; - // Don't request bus, since we already have it - return allocateMissBuffer(pkt, curTick, false); + Addr pf_addr = blockAlign(pkt->getAddr()); + if (!tags->findBlock(pf_addr) && !mshrQueue.findMatch(pf_addr)) { + // Update statistic on number of prefetches issued + // (hwpf_mshr_misses) + mshr_misses[pkt->cmdToIndex()][0/*pkt->req->threadId()*/]++; + // Don't request bus, since we already have it + return allocateMissBuffer(pkt, curTick, false); + } } } diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc index f0e244a09b..ad7a0c8827 100644 --- a/src/mem/cache/prefetch/base.cc +++ b/src/mem/cache/prefetch/base.cc @@ -45,7 +45,6 @@ BasePrefetcher::BasePrefetcher(const BaseCacheParams *p) : size(p->prefetcher_size), pageStop(!p->prefetch_past_page), serialSquash(p->prefetch_serial_squash), - cacheCheckPush(p->prefetch_cache_check_push), onlyData(p->prefetch_data_accesses_only) { } @@ -143,9 +142,6 @@ BasePrefetcher::getPacket() do { pkt = *pf.begin(); pf.pop_front(); - if (!cacheCheckPush) { - keep_trying = cache->inCache(pkt->getAddr()); - } if (keep_trying) { DPRINTF(HWPrefetch, "addr 0x%x in cache, skipping\n", @@ -226,18 +222,6 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick time) "inserting into prefetch queue with delay %d time %d\n", addr, *delayIter, time); - // Check if it is already in the cache - if (cacheCheckPush && cache->inCache(addr)) { - DPRINTF(HWPrefetch, "Prefetch addr already in cache\n"); - continue; - } - - // Check if it is already in the miss_queue - if (cache->inMissQueue(addr)) { - DPRINTF(HWPrefetch, "Prefetch addr already in miss queue\n"); - continue; - } - // Check if it is already in the pf buffer if (inPrefetch(addr) != pf.end()) { pfBufferHit++; diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh index b5f33a455c..e3c0cbf163 100644 --- a/src/mem/cache/prefetch/base.hh +++ b/src/mem/cache/prefetch/base.hh @@ -68,10 +68,6 @@ class BasePrefetcher /** Do we remove prefetches with later times than a new miss.*/ bool serialSquash; - /** Do we check if it is in the cache when inserting into buffer, - or removing.*/ - bool cacheCheckPush; - /** Do we prefetch on only data reads, or on inst reads as well. */ bool onlyData; From f67963078883cdb62094ca187a40a79d773251a7 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 26 Sep 2009 10:50:50 -0700 Subject: [PATCH 031/160] Minor cleanup: Use the blockAlign() method where it applies in the cache. --- src/mem/cache/base.hh | 2 +- src/mem/cache/cache_impl.hh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh index 24f9933833..c245fecd24 100644 --- a/src/mem/cache/base.hh +++ b/src/mem/cache/base.hh @@ -379,7 +379,7 @@ class BaseCache : public MemObject } - Addr blockAlign(Addr addr) const { return (addr & ~(blkSize - 1)); } + Addr blockAlign(Addr addr) const { return (addr & ~(Addr(blkSize - 1))); } const Range &getAddrRange() const { return addrRange; } diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index d8630c1f5d..429928c796 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -449,7 +449,7 @@ Cache::timingAccess(PacketPtr pkt) } else { // miss - Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); + Addr blk_addr = blockAlign(pkt->getAddr()); MSHR *mshr = mshrQueue.findMatch(blk_addr); if (mshr) { @@ -692,7 +692,7 @@ Cache::functionalAccess(PacketPtr pkt, CachePort *incomingPort, CachePort *otherSidePort) { - Addr blk_addr = pkt->getAddr() & ~(blkSize - 1); + Addr blk_addr = blockAlign(pkt->getAddr()); BlkType *blk = tags->findBlock(pkt->getAddr()); pkt->pushLabel(name()); @@ -1162,7 +1162,7 @@ Cache::snoopTiming(PacketPtr pkt) BlkType *blk = tags->findBlock(pkt->getAddr()); - Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); + Addr blk_addr = blockAlign(pkt->getAddr()); MSHR *mshr = mshrQueue.findMatch(blk_addr); // Let the MSHR itself track the snoop and decide whether we want From 4bec4702e9338735f58f0769f853ddff3657850e Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 26 Sep 2009 10:50:50 -0700 Subject: [PATCH 032/160] O3: Add flag to control whether faulting instructions are traced. When enabled, faulting instructions appear in the trace twice (once when they fault and again when they're re-executed). This flag is set by the Exec compound flag for backwards compatibility. --- src/cpu/SConscript | 5 +++-- src/cpu/o3/commit_impl.hh | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cpu/SConscript b/src/cpu/SConscript index ea79b622c7..b89a589c62 100644 --- a/src/cpu/SConscript +++ b/src/cpu/SConscript @@ -160,6 +160,7 @@ TraceFlag('DynInst') TraceFlag('ExecEnable') TraceFlag('ExecCPSeq') TraceFlag('ExecEffAddr') +TraceFlag('ExecFaulting', 'Trace faulting instructions') TraceFlag('ExecFetchSeq') TraceFlag('ExecOpClass') TraceFlag('ExecRegDelta') @@ -176,6 +177,6 @@ TraceFlag('PCEvent') TraceFlag('Quiesce') CompoundFlag('Exec', [ 'ExecEnable', 'ExecTicks', 'ExecOpClass', 'ExecThread', - 'ExecEffAddr', 'ExecResult', 'ExecSymbol', 'ExecMicro' ]) + 'ExecEffAddr', 'ExecResult', 'ExecSymbol', 'ExecMicro', 'ExecFaulting' ]) CompoundFlag('ExecNoTicks', [ 'ExecEnable', 'ExecOpClass', 'ExecThread', - 'ExecEffAddr', 'ExecResult', 'ExecMicro' ]) + 'ExecEffAddr', 'ExecResult', 'ExecMicro', 'ExecFaulting' ]) diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index aa0f792726..cb5f238144 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -1076,9 +1076,11 @@ DefaultCommit::commitHead(DynInstPtr &head_inst, unsigned inst_num) commitStatus[tid] = TrapPending; if (head_inst->traceData) { - head_inst->traceData->setFetchSeq(head_inst->seqNum); - head_inst->traceData->setCPSeq(thread[tid]->numInst); - head_inst->traceData->dump(); + if (DTRACE(ExecFaulting)) { + head_inst->traceData->setFetchSeq(head_inst->seqNum); + head_inst->traceData->setCPSeq(thread[tid]->numInst); + head_inst->traceData->dump(); + } delete head_inst->traceData; head_inst->traceData = NULL; } From 7a8ee4f40a4fbbbbf4d6a8e5b6a81d0486b1a1b6 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 26 Sep 2009 10:50:50 -0700 Subject: [PATCH 033/160] rundiff: Don't flush stdout until after postcontext is printed. --- util/rundiff | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/util/rundiff b/util/rundiff index cd2527e543..7e0a770572 100755 --- a/util/rundiff +++ b/util/rundiff @@ -166,7 +166,11 @@ sub printdiff # Set $postcontext to print the next $postcontext_lines matching lines. $postcontext = $postcontext_lines; - STDOUT->flush(); + # Normally we flush after the postcontext lines are printed, but if + # the user has decreed that there aren't any we need to flush now + if ($postcontext == 0) { + STDOUT->flush(); + } } @@ -291,10 +295,12 @@ while (1) { # figure out what to do with this line if ($postcontext > 0) { # we're in the post-context of a diff: print it - $postcontext--; print ' ', $l1; $lineno1++; $lineno2++; + if (--$postcontext == 0) { + STDOUT->flush(); + } } else { # we're in the middle of a matching region... save this From 160bcf4442df44b410c61c2d842696cb23b796f7 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 26 Sep 2009 12:51:37 -0700 Subject: [PATCH 034/160] python: Fix m5.defines so grabbing flags works correctly --- src/SConscript | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/SConscript b/src/SConscript index 705d76b1dc..35753ce4ca 100644 --- a/src/SConscript +++ b/src/SConscript @@ -411,9 +411,12 @@ buildEnv = m5.util.SmartDict($build_env) hgRev = '$hg_info' compileDate = m5.internal.core.compileDate -for k,v in m5.internal.core.__dict__.iteritems(): - if k.startswith('flag_'): - setattr(buildEnv, k[5:], v) +_globals = globals() +for key,val in m5.internal.core.__dict__.iteritems(): + if key.startswith('flag_'): + flag = key[5:] + _globals[flag] = val +del _globals """) code.write(str(target[0])) From 1290a5f340db08215bee9b0c02173ead53b95050 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Tue, 29 Sep 2009 18:03:10 -0400 Subject: [PATCH 035/160] commit Soumyaroop's bug catch about max_insts_all_threads --- src/cpu/base.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/base.cc b/src/cpu/base.cc index e4cb793447..556e7ec6f6 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -151,7 +151,7 @@ BaseCPU::BaseCPU(Params *p) *counter = numThreads; for (ThreadID tid = 0; tid < numThreads; ++tid) { Event *event = new CountedExitEvent(cause, *counter); - comInstEventQueue[tid]->schedule(event, p->max_insts_any_thread); + comInstEventQueue[tid]->schedule(event, p->max_insts_all_threads); } } From f09f84da6ef01870991345539edae46b401cf311 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 1 Oct 2009 09:35:06 -0400 Subject: [PATCH 036/160] inorder-debug: print out workload --- src/cpu/inorder/cpu.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 969359fae8..1e3fdc40e0 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -224,19 +224,19 @@ InOrderCPU::InOrderCPU(Params *params) for (ThreadID tid = 0; tid < numThreads; ++tid) { #if FULL_SYSTEM // SMT is not supported in FS mode yet. - assert(this->numThreads == 1); - this->thread[tid] = new Thread(this, 0); + assert(numThreads == 1); + thread[tid] = new Thread(this, 0); #else if (tid < (ThreadID)params->workload.size()) { DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n", - tid, this->thread[tid]); - this->thread[tid] = + tid, params->workload[tid]->prog_fname); + thread[tid] = new Thread(this, tid, params->workload[tid]); } else { //Allocate Empty thread so M5 can use later //when scheduling threads to CPU Process* dummy_proc = params->workload[0]; - this->thread[tid] = new Thread(this, tid, dummy_proc); + thread[tid] = new Thread(this, tid, dummy_proc); } #endif From 86f3bec76d1bd14ed11188877dd3039d0bcfd489 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 2 Oct 2009 01:32:00 -0700 Subject: [PATCH 037/160] SE mode: Make the direction anonymous mmaps move through memory configurable. --- src/kern/operatingsystem.hh | 4 ++++ src/sim/syscall_emul.hh | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/kern/operatingsystem.hh b/src/kern/operatingsystem.hh index 47e64ffd93..6574e3c6bb 100644 --- a/src/kern/operatingsystem.hh +++ b/src/kern/operatingsystem.hh @@ -122,6 +122,10 @@ class OperatingSystem { static int openSpecialFile(std::string path, LiveProcess *process, ThreadContext *tc); + static const bool mmapGrowsUp = true; + + static bool mmapGrowsDown() { return false; } + }; // class OperatingSystem diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index c9ce4b14fb..e45a6c7975 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -978,9 +978,14 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) } // pick next address from our "mmap region" - start = p->mmap_end; + if (OS::mmapGrowsDown()) { + start = p->mmap_end - length; + p->mmap_end = start; + } else { + start = p->mmap_end; + p->mmap_end += length; + } p->pTable->allocate(start, length); - p->mmap_end += length; if (!(flags & OS::TGT_MAP_ANONYMOUS)) { warn("allowing mmap of file @ fd %d. " From 44ceb80c2dd1c4991357292ca27809b5012b9556 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 2 Oct 2009 01:32:58 -0700 Subject: [PATCH 038/160] X86: Make successive anonymous mmaps move down in 32 bit SE mode Linux. --- src/arch/x86/linux/linux.hh | 4 +++- src/arch/x86/process.cc | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index d5bead8f3d..a810d4a796 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -190,7 +190,9 @@ class X86Linux32 : public Linux uint32_t totalhigh; /* Total high memory size */ uint32_t freehigh; /* Available high memory size */ uint32_t mem_unit; /* Memory unit size in bytes */ - } tgt_sysinfo; + } tgt_sysinfo; + + static bool mmapGrowsDown() { return true; } }; #endif diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 4082e568cd..f7678443d1 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -184,7 +184,7 @@ I386LiveProcess::I386LiveProcess(LiveProcessParams *params, // Set up region for mmaps. This was determined empirically and may not // always be correct. - mmap_start = mmap_end = (Addr)0xf7ffd000ULL; + mmap_start = mmap_end = (Addr)0xf7ffe000ULL; } SyscallDesc* From 8a761c44af607c1a05642d32cbaa6b97106e6b7d Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 3 Oct 2009 18:07:39 -0700 Subject: [PATCH 039/160] bus: add assertion to catch illegal retry on mem-inhibited transaction. --- src/mem/bus.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 001c37a245..cac08d1a81 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -244,6 +244,9 @@ Bus::recvTiming(PacketPtr pkt) // Packet not successfully sent. Leave or put it on the retry list. // illegal to block responses... can lead to deadlock assert(!pkt->isResponse()); + // It's also illegal to force a transaction to retry after + // someone else has committed to respond. + assert(!pkt->memInhibitAsserted()); DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x TGT RETRY\n", src, pkt->getDest(), pkt->cmdString(), pkt->getAddr()); addToRetryList(src_port); From 2b181fc3e7244fcfc169428827f0baf0fde03895 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 6 Oct 2009 20:54:04 -0400 Subject: [PATCH 040/160] mips: update hello-ruby stats --- .../ref/mips/linux/simple-atomic-ruby/simerr | 18 ------------------ .../ref/mips/linux/simple-atomic-ruby/simout | 11 +++++------ .../mips/linux/simple-atomic-ruby/stats.txt | 18 +++++++++--------- .../ref/mips/linux/simple-timing-ruby/simerr | 18 ------------------ .../ref/mips/linux/simple-timing-ruby/simout | 11 +++++------ .../mips/linux/simple-timing-ruby/stats.txt | 18 +++++++++--------- 6 files changed, 28 insertions(+), 66 deletions(-) diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simerr b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simerr index 187d1a0acf..aece78b324 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simerr +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simerr @@ -1,23 +1,5 @@ ["-r", "tests/configs/../../src/mem/ruby/config/MI_example-homogeneous.rb", "-p", "1", "-m", "1", "-s", "1024"] print config: 1 -Creating new MessageBuffer for 0 0 -Creating new MessageBuffer for 0 1 -Creating new MessageBuffer for 0 2 -Creating new MessageBuffer for 0 3 -Creating new MessageBuffer for 0 4 -Creating new MessageBuffer for 0 5 -Creating new MessageBuffer for 1 0 -Creating new MessageBuffer for 1 1 -Creating new MessageBuffer for 1 2 -Creating new MessageBuffer for 1 3 -Creating new MessageBuffer for 1 4 -Creating new MessageBuffer for 1 5 -Creating new MessageBuffer for 2 0 -Creating new MessageBuffer for 2 1 -Creating new MessageBuffer for 2 2 -Creating new MessageBuffer for 2 3 -Creating new MessageBuffer for 2 4 -Creating new MessageBuffer for 2 5 warn: Sockets disabled, not accepting gdb connections For more information see: http://www.m5sim.org/warn/d946bea6 hack: be nice to actually delete the event here diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simout b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simout index a97b34ba79..7408d6fc97 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simout +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/simout @@ -5,14 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Jul 6 2009 11:05:29 -M5 revision d3635cac686a 6289 default ruby_refs.diff qtip tip -M5 started Jul 6 2009 11:11:09 -M5 executing on maize +M5 compiled Oct 6 2009 20:51:47 +M5 revision 300266bf68ec+ 6674+ default tip +M5 started Oct 6 2009 20:51:48 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-atomic-ruby -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-atomic-ruby Global frequency set at 1000000000000 ticks per second - Debug: Adding to filter: 'q' (Queue) info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 2828000 because target called exit() +Exiting @ tick 2842500 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/stats.txt b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/stats.txt index 8b9ded108b..94d67cedda 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/simple-atomic-ruby/stats.txt @@ -1,13 +1,13 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 47334 # Simulator instruction rate (inst/s) -host_mem_usage 1362452 # Number of bytes of host memory used -host_seconds 0.12 # Real time elapsed on the host -host_tick_rate 23634419 # Simulator tick rate (ticks/s) +host_inst_rate 27672 # Simulator instruction rate (inst/s) +host_mem_usage 1265116 # Number of bytes of host memory used +host_seconds 0.21 # Real time elapsed on the host +host_tick_rate 13820616 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated +sim_insts 5685 # Number of instructions simulated sim_seconds 0.000003 # Number of seconds simulated -sim_ticks 2828000 # Number of ticks simulated +sim_ticks 2842500 # Number of ticks simulated system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits system.cpu.dtb.misses 0 # DTB misses @@ -28,9 +28,9 @@ system.cpu.itb.write_accesses 0 # DT system.cpu.itb.write_hits 0 # DTB write hits system.cpu.itb.write_misses 0 # DTB write misses system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 5657 # number of cpu cycles simulated -system.cpu.num_insts 5656 # Number of instructions executed -system.cpu.num_refs 2055 # Number of memory references +system.cpu.numCycles 5686 # number of cpu cycles simulated +system.cpu.num_insts 5685 # Number of instructions executed +system.cpu.num_refs 2058 # Number of memory references system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simerr b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simerr index 187d1a0acf..aece78b324 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simerr +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simerr @@ -1,23 +1,5 @@ ["-r", "tests/configs/../../src/mem/ruby/config/MI_example-homogeneous.rb", "-p", "1", "-m", "1", "-s", "1024"] print config: 1 -Creating new MessageBuffer for 0 0 -Creating new MessageBuffer for 0 1 -Creating new MessageBuffer for 0 2 -Creating new MessageBuffer for 0 3 -Creating new MessageBuffer for 0 4 -Creating new MessageBuffer for 0 5 -Creating new MessageBuffer for 1 0 -Creating new MessageBuffer for 1 1 -Creating new MessageBuffer for 1 2 -Creating new MessageBuffer for 1 3 -Creating new MessageBuffer for 1 4 -Creating new MessageBuffer for 1 5 -Creating new MessageBuffer for 2 0 -Creating new MessageBuffer for 2 1 -Creating new MessageBuffer for 2 2 -Creating new MessageBuffer for 2 3 -Creating new MessageBuffer for 2 4 -Creating new MessageBuffer for 2 5 warn: Sockets disabled, not accepting gdb connections For more information see: http://www.m5sim.org/warn/d946bea6 hack: be nice to actually delete the event here diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simout b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simout index 8519ea0e24..6c7350461e 100755 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simout +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/simout @@ -5,14 +5,13 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Jul 6 2009 11:05:29 -M5 revision d3635cac686a 6289 default ruby_refs.diff qtip tip -M5 started Jul 6 2009 11:11:09 -M5 executing on maize +M5 compiled Oct 6 2009 20:43:14 +M5 revision 300266bf68ec 6674 default tip +M5 started Oct 6 2009 20:47:38 +M5 executing on zooks command line: build/MIPS_SE/m5.fast -d build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-timing-ruby -re tests/run.py build/MIPS_SE/tests/fast/quick/00.hello/mips/linux/simple-timing-ruby Global frequency set at 1000000000000 ticks per second - Debug: Adding to filter: 'q' (Queue) info: Entering event queue @ 0. Starting simulation... info: Increasing stack size by one page. Hello World! -Exiting @ tick 23131000 because target called exit() +Exiting @ tick 23227000 because target called exit() diff --git a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/stats.txt b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/stats.txt index 95f42aecde..15c68a6b08 100644 --- a/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/stats.txt +++ b/tests/quick/00.hello/ref/mips/linux/simple-timing-ruby/stats.txt @@ -1,13 +1,13 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 8081 # Simulator instruction rate (inst/s) -host_mem_usage 1362552 # Number of bytes of host memory used -host_seconds 0.70 # Real time elapsed on the host -host_tick_rate 33041595 # Simulator tick rate (ticks/s) +host_inst_rate 3701 # Simulator instruction rate (inst/s) +host_mem_usage 1265204 # Number of bytes of host memory used +host_seconds 1.54 # Real time elapsed on the host +host_tick_rate 15119806 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 5656 # Number of instructions simulated +sim_insts 5685 # Number of instructions simulated sim_seconds 0.000023 # Number of seconds simulated -sim_ticks 23131000 # Number of ticks simulated +sim_ticks 23227000 # Number of ticks simulated system.cpu.dtb.accesses 0 # DTB accesses system.cpu.dtb.hits 0 # DTB hits system.cpu.dtb.misses 0 # DTB misses @@ -28,9 +28,9 @@ system.cpu.itb.write_accesses 0 # DT system.cpu.itb.write_hits 0 # DTB write hits system.cpu.itb.write_misses 0 # DTB write misses system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 46262 # number of cpu cycles simulated -system.cpu.num_insts 5656 # Number of instructions executed -system.cpu.num_refs 2055 # Number of memory references +system.cpu.numCycles 46454 # number of cpu cycles simulated +system.cpu.num_insts 5685 # Number of instructions executed +system.cpu.num_refs 2058 # Number of memory references system.cpu.workload.PROG:num_syscalls 13 # Number of system calls ---------- End Simulation Statistics ---------- From 30a185dcd04cc7797609398219482d03a68509f9 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sat, 10 Oct 2009 22:31:56 -0700 Subject: [PATCH 041/160] Hook up the munmap() syscall for 32-bit x86. This is straightforward, as munmapFunc() doesn't do anything. I've tested it with code running munmap() just in case. --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 52352ee807..affe2d6ea2 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -598,7 +598,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 88 */ SyscallDesc("reboot", unimplementedFunc), /* 89 */ SyscallDesc("readdir", unimplementedFunc), /* 90 */ SyscallDesc("mmap", unimplementedFunc), - /* 91 */ SyscallDesc("munmap", unimplementedFunc), + /* 91 */ SyscallDesc("munmap", munmapFunc), /* 92 */ SyscallDesc("truncate", unimplementedFunc), /* 93 */ SyscallDesc("ftruncate", unimplementedFunc), /* 94 */ SyscallDesc("fchmod", unimplementedFunc), From 28204b2a964983738726428269e61833f4e1dce9 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Thu, 15 Oct 2009 15:15:24 -0700 Subject: [PATCH 042/160] fixed MC146818 checkpointing bug and added isa serialization calls to simple_thread --- src/cpu/simple_thread.cc | 10 ++++++++++ src/dev/mc146818.cc | 22 ++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 92c6ad69b5..f18634198e 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -199,6 +199,11 @@ SimpleThread::serialize(ostream &os) SERIALIZE_SCALAR(nextPC); SERIALIZE_SCALAR(nextNPC); // thread_num and cpu_id are deterministic from the config + + // + // Now must serialize all the ISA dependent state + // + isa.serialize(os); } @@ -214,6 +219,11 @@ SimpleThread::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(nextPC); UNSERIALIZE_SCALAR(nextNPC); // thread_num and cpu_id are deterministic from the config + + // + // Now must unserialize all the ISA dependent state + // + isa.unserialize(cp, section); } #if FULL_SYSTEM diff --git a/src/dev/mc146818.cc b/src/dev/mc146818.cc index b25b015d23..0bb6558c81 100644 --- a/src/dev/mc146818.cc +++ b/src/dev/mc146818.cc @@ -207,6 +207,15 @@ MC146818::serialize(const string &base, ostream &os) arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data)); paramOut(os, base + ".stat_regA", stat_regA); paramOut(os, base + ".stat_regB", stat_regB); + + // + // save the timer tick and rtc clock tick values to correctly reschedule + // them during unserialize + // + Tick rtcTimerInterruptTickOffset = event.when() - curTick; + SERIALIZE_SCALAR(rtcTimerInterruptTickOffset); + Tick rtcClockTickOffset = event.when() - curTick; + SERIALIZE_SCALAR(rtcClockTickOffset); } void @@ -218,10 +227,15 @@ MC146818::unserialize(const string &base, Checkpoint *cp, paramIn(cp, section, base + ".stat_regA", stat_regA); paramIn(cp, section, base + ".stat_regB", stat_regB); - // We're not unserializing the event here, but we need to - // rescehedule the event since curTick was moved forward by the - // checkpoint - reschedule(event, curTick + event.interval); + // + // properly schedule the timer and rtc clock events + // + Tick rtcTimerInterruptTickOffset; + UNSERIALIZE_SCALAR(rtcTimerInterruptTickOffset); + reschedule(event, curTick + rtcTimerInterruptTickOffset); + Tick rtcClockTickOffset; + UNSERIALIZE_SCALAR(rtcClockTickOffset); + reschedule(tickEvent, curTick + rtcClockTickOffset); } MC146818::RTCEvent::RTCEvent(MC146818 * _parent, Tick i) From 912f3d707412b9a6001fe816d7a56a9743c86e34 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Fri, 16 Oct 2009 08:15:53 -0700 Subject: [PATCH 043/160] removed libruby file reference from ruby_se.py --- configs/example/ruby_se.py | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/example/ruby_se.py b/configs/example/ruby_se.py index 76668f7631..e7e9300776 100644 --- a/configs/example/ruby_se.py +++ b/configs/example/ruby_se.py @@ -138,7 +138,6 @@ rubymem = RubyMemory( range = AddrRange("512MB"), clock = "1GHz", num_cpus = np, - libruby_file = "src/mem/ruby/amd64-linux/generated/MOESI_CMP_directory/bin/libruby.so", config_file = "ruby.config", stats_file = "m5out/ruby.stats" ) From 010b13c937c80b9138d5c70fda6c47ea75d2a9b3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 17 Oct 2009 01:13:41 -0700 Subject: [PATCH 044/160] ISA: Fix compilation. --- src/arch/alpha/isa.cc | 4 ++-- src/arch/alpha/isa.hh | 5 +++-- src/arch/arm/isa.hh | 5 +++-- src/arch/mips/isa.hh | 7 +++++-- src/cpu/simple_thread.cc | 4 ++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/arch/alpha/isa.cc b/src/arch/alpha/isa.cc index eee391a0de..8b6da36494 100644 --- a/src/arch/alpha/isa.cc +++ b/src/arch/alpha/isa.cc @@ -36,7 +36,7 @@ namespace AlphaISA { void -ISA::serialize(std::ostream &os) +ISA::serialize(EventManager *em, std::ostream &os) { SERIALIZE_SCALAR(fpcr); SERIALIZE_SCALAR(uniq); @@ -46,7 +46,7 @@ ISA::serialize(std::ostream &os) } void -ISA::unserialize(Checkpoint *cp, const std::string §ion) +ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string §ion) { UNSERIALIZE_SCALAR(fpcr); UNSERIALIZE_SCALAR(uniq); diff --git a/src/arch/alpha/isa.hh b/src/arch/alpha/isa.hh index 622d1da4cc..574b508419 100644 --- a/src/arch/alpha/isa.hh +++ b/src/arch/alpha/isa.hh @@ -83,8 +83,9 @@ namespace AlphaISA intr_flag = 0; } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion); void reset(std::string core_name, ThreadID num_threads, unsigned num_vpes, BaseCPU *_cpu) diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 2315afa9e8..9b21c03cd7 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -95,9 +95,10 @@ namespace ArmISA return reg; } - void serialize(std::ostream &os) + void serialize(EventManager *em, std::ostream &os) {} - void unserialize(Checkpoint *cp, const std::string §ion) + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion) {} ISA() diff --git a/src/arch/mips/isa.hh b/src/arch/mips/isa.hh index 15c043dc06..165adff83d 100644 --- a/src/arch/mips/isa.hh +++ b/src/arch/mips/isa.hh @@ -172,8 +172,11 @@ namespace MipsISA return reg; } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os) + {} + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion) + {} }; } diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index f18634198e..ad69719eea 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -203,7 +203,7 @@ SimpleThread::serialize(ostream &os) // // Now must serialize all the ISA dependent state // - isa.serialize(os); + isa.serialize(cpu, os); } @@ -223,7 +223,7 @@ SimpleThread::unserialize(Checkpoint *cp, const std::string §ion) // // Now must unserialize all the ISA dependent state // - isa.unserialize(cp, section); + isa.unserialize(cpu, cp, section); } #if FULL_SYSTEM From 22dc2b5595519d5fc7ca93854053b22a359e331b Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 16 Oct 2009 13:54:20 -0400 Subject: [PATCH 045/160] Ignore rt_sigaction() syscalls on x86 and x86_64 This is currently how alpha handles this syscall. This is needed for the gcc spec2k benchmarks to run. --- src/arch/x86/linux/syscalls.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index affe2d6ea2..74a6ad0b76 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -241,7 +241,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 10 */ SyscallDesc("mprotect", unimplementedFunc), /* 11 */ SyscallDesc("munmap", munmapFunc), /* 12 */ SyscallDesc("brk", brkFunc), - /* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc), + /* 13 */ SyscallDesc("rt_sigaction", ignoreFunc), /* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc), /* 16 */ SyscallDesc("ioctl", unimplementedFunc), @@ -681,7 +681,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 171 */ SyscallDesc("getresgid", unimplementedFunc), /* 172 */ SyscallDesc("prctl", unimplementedFunc), /* 173 */ SyscallDesc("rt_sigreturn", unimplementedFunc), - /* 174 */ SyscallDesc("rt_sigaction", unimplementedFunc), + /* 174 */ SyscallDesc("rt_sigaction", ignoreFunc), /* 175 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc), /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), From 56154cff5eab4a28a6d86a820a4364f99889555f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 19 Oct 2009 17:29:34 -0400 Subject: [PATCH 046/160] Enable getuid and getgid related syscalls on X86_SE I've tested these on x86 and they work as expected. In theory for 32-bit x86 we should have some sort of special handling for the legacy 16-bit uid/gid syscalls, but in practice modern toolchains don't use the 16-bit versions, and m5 sets the uid and gid values to be less than 16-bits anyway. This fix is needed for the perl spec2k benchmarks to run. --- src/arch/x86/linux/syscalls.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 74a6ad0b76..2b54843f36 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -531,7 +531,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 21 */ SyscallDesc("mount", unimplementedFunc), /* 22 */ SyscallDesc("umount", unimplementedFunc), /* 23 */ SyscallDesc("setuid", unimplementedFunc), - /* 24 */ SyscallDesc("getuid", unimplementedFunc), + /* 24 */ SyscallDesc("getuid", getuidFunc), /* 25 */ SyscallDesc("stime", unimplementedFunc), /* 26 */ SyscallDesc("ptrace", unimplementedFunc), /* 27 */ SyscallDesc("alarm", unimplementedFunc), @@ -554,10 +554,10 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 44 */ SyscallDesc("prof", unimplementedFunc), /* 45 */ SyscallDesc("brk", brkFunc), /* 46 */ SyscallDesc("setgid", unimplementedFunc), - /* 47 */ SyscallDesc("getgid", unimplementedFunc), + /* 47 */ SyscallDesc("getgid", getgidFunc), /* 48 */ SyscallDesc("signal", unimplementedFunc), - /* 49 */ SyscallDesc("geteuid", unimplementedFunc), - /* 50 */ SyscallDesc("getegid", unimplementedFunc), + /* 49 */ SyscallDesc("geteuid", geteuidFunc), + /* 50 */ SyscallDesc("getegid", getegidFunc), /* 51 */ SyscallDesc("acct", unimplementedFunc), /* 52 */ SyscallDesc("umount2", unimplementedFunc), /* 53 */ SyscallDesc("lock", unimplementedFunc), @@ -706,10 +706,10 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 196 */ SyscallDesc("lstat64", unimplementedFunc), /* 197 */ SyscallDesc("fstat64", fstat64Func), /* 198 */ SyscallDesc("lchown32", unimplementedFunc), - /* 199 */ SyscallDesc("getuid32", unimplementedFunc), - /* 200 */ SyscallDesc("getgid32", unimplementedFunc), - /* 201 */ SyscallDesc("geteuid32", unimplementedFunc), - /* 202 */ SyscallDesc("getegid32", unimplementedFunc), + /* 199 */ SyscallDesc("getuid32", getuidFunc), + /* 200 */ SyscallDesc("getgid32", getgidFunc), + /* 201 */ SyscallDesc("geteuid32", geteuidFunc), + /* 202 */ SyscallDesc("getegid32", getegidFunc), /* 203 */ SyscallDesc("setreuid32", unimplementedFunc), /* 204 */ SyscallDesc("setregid32", unimplementedFunc), /* 205 */ SyscallDesc("getgroups32", unimplementedFunc), From 6c60db8ce99eabdbfcbe0f78a50817494142e39e Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:57 -0700 Subject: [PATCH 047/160] syscall: Implementation of the times system call --- src/kern/linux/linux.hh | 11 +++++++++++ src/sim/syscall_emul.hh | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 7c16228ea1..2df323712c 100644 --- a/src/kern/linux/linux.hh +++ b/src/kern/linux/linux.hh @@ -136,6 +136,17 @@ class Linux : public OperatingSystem int64_t tv_usec; //!< microseconds }; + /// Clock ticks per second, for times(). + static const int _SC_CLK_TCK = 100; + + /// For times(). + struct tms { + int64_t tms_utime; //!< user time + int64_t tms_stime; //!< system time + int64_t tms_cutime; //!< user time of children + int64_t tms_cstime; //!< system time of children + }; + // For writev/readv struct tgt_iovec { uint64_t iov_base; // void * diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index e45a6c7975..ce7c7fa878 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -1131,6 +1131,30 @@ getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return 0; } +/// Target times() function. +template +SyscallReturn +timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + TypedBufferArg bufp(process->getSyscallArg(tc, 0)); + + // Fill in the time structure (in clocks) + int64_t clocks = curTick * OS::_SC_CLK_TCK / Clock::Int::s; + bufp->tms_utime = clocks; + bufp->tms_stime = 0; + bufp->tms_cutime = 0; + bufp->tms_cstime = 0; + + // Convert to host endianness + bufp->tms_utime = htog(bufp->tms_utime); + + // Write back + bufp.copyOut(tc->getMemPort()); + + // Return clock ticks since system boot + return clocks; +} From 7cdd5316abaf91755edd9186d3836ff371902146 Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:57 -0700 Subject: [PATCH 048/160] syscall: Implementation of the time system call. --- src/kern/linux/linux.hh | 1 + src/sim/syscall_emul.hh | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 2df323712c..736213762b 100644 --- a/src/kern/linux/linux.hh +++ b/src/kern/linux/linux.hh @@ -62,6 +62,7 @@ class Linux : public OperatingSystem typedef uint64_t size_t; typedef uint64_t off_t; typedef int64_t time_t; + typedef int64_t clock_t; typedef uint32_t uid_t; typedef uint32_t gid_t; //@} diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index ce7c7fa878..6937e35f0d 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -1156,6 +1156,25 @@ timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return clocks; } +/// Target time() function. +template +SyscallReturn +timeFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + typename OS::time_t sec, usec; + getElapsedTime(sec, usec); + sec += seconds_since_epoch; + + Addr taddr = (Addr)process->getSyscallArg(tc, 0); + if(taddr != 0) { + typename OS::time_t t = sec; + t = htog(t); + TranslatingPort *p = tc->getMemPort(); + p->writeBlob(taddr, (uint8_t*)&t, (int)sizeof(typename OS::time_t)); + } + return sec; +} #endif // __SIM_SYSCALL_EMUL_HH__ From c32d919bc07d87e5fc59d98cb58e9143182c1aef Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:58 -0700 Subject: [PATCH 049/160] syscall: Implementation of the ftruncate64 system call. --- src/sim/syscall_emul.cc | 16 ++++++++++++++++ src/sim/syscall_emul.hh | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index bd66594afe..9a797bcdb0 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -404,6 +404,22 @@ ftruncateFunc(SyscallDesc *desc, int num, return (result == -1) ? -errno : result; } +SyscallReturn +ftruncate64Func(SyscallDesc *desc, int num, + LiveProcess *process, ThreadContext *tc) +{ + int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + + if (fd < 0) + return -EBADF; + + // I'm not sure why, but the length argument is in arg reg 3 + loff_t length = process->getSyscallArg(tc, 3); + + int result = ftruncate64(fd, length); + return (result == -1) ? -errno : result; +} + SyscallReturn umaskFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 6937e35f0d..f5e8a02e5c 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -260,6 +260,11 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); +/// Target ftruncate64() handler. +SyscallReturn ftruncate64Func(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + + /// Target umask() handler. SyscallReturn umaskFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); From cc21f862e2d6ad6ba8d5332d6bbc05e58e55bfa0 Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:58 -0700 Subject: [PATCH 050/160] syscall: Fix conversion of the stat64 buffer during system calls. --- src/sim/syscall_emul.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index f5e8a02e5c..21f8201c8d 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -469,7 +469,7 @@ copyOutStat64Buf(TranslatingPort * mem, Addr addr, { typedef TypedBufferArg tgt_stat_buf; tgt_stat_buf tgt(addr); - convertStatBuf(tgt, host, fakeTTY); + convertStat64Buf(tgt, host, fakeTTY); tgt.copyOut(mem); } From 03da1e53c24aa86a3b04216c3d2d002fd9020ea0 Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:58 -0700 Subject: [PATCH 051/160] syscall: Zero out memory that already exists during the brk system call. Glibc often assumes that memory it receives from the kernel after a brk system call will contain only zeros. This is important during a calloc, because it won't clear the new memory itself. In the simulator, if the new page exists, it will be cleared using this patch, to mimic the kernel's functionality. --- src/sim/syscall_emul.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 9a797bcdb0..13ad043111 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -144,6 +144,24 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) if (!p->pTable->translate(gen.addr())) p->pTable->allocate(roundDown(gen.addr(), VMPageSize), VMPageSize); + + // if the address is already there, zero it out + else { + uint8_t zero = 0; + TranslatingPort *tp = tc->getMemPort(); + + // split non-page aligned accesses + Addr next_page = roundUp(gen.addr(), VMPageSize); + uint32_t size_needed = next_page - gen.addr(); + tp->memsetBlob(gen.addr(), zero, size_needed); + if (gen.addr() + VMPageSize > next_page && + next_page < new_brk && + p->pTable->translate(next_page)) + { + size_needed = VMPageSize - size_needed; + tp->memsetBlob(next_page, zero, size_needed); + } + } } } From 5fe0762ee44b59331a9e00c99eea4be5d4571453 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 24 Oct 2009 10:53:58 -0700 Subject: [PATCH 052/160] tests: update test for slight change due to the change in brk. --- .../60.bzip2/ref/alpha/tru64/o3-timing/simout | 6 +-- .../ref/alpha/tru64/o3-timing/stats.txt | 46 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simout b/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simout index 84bba46f10..26e42fa14b 100755 --- a/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simout +++ b/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/simout @@ -5,9 +5,9 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Jul 6 2009 11:03:45 -M5 revision d3635cac686a 6289 default ruby_refs.diff qtip tip -M5 started Jul 6 2009 11:56:32 +M5 compiled Oct 22 2009 13:11:07 +M5 revision e406bb83c56f 6682 default qtip tip syscall-ioctl.patch +M5 started Oct 22 2009 13:42:59 M5 executing on maize command line: build/ALPHA_SE/m5.fast -d build/ALPHA_SE/tests/fast/long/60.bzip2/alpha/tru64/o3-timing -re tests/run.py build/ALPHA_SE/tests/fast/long/60.bzip2/alpha/tru64/o3-timing Global frequency set at 1000000000000 ticks per second diff --git a/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stats.txt b/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stats.txt index 3a8e7864ac..d858d0b22b 100644 --- a/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stats.txt +++ b/tests/long/60.bzip2/ref/alpha/tru64/o3-timing/stats.txt @@ -1,9 +1,9 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 222565 # Simulator instruction rate (inst/s) -host_mem_usage 190364 # Number of bytes of host memory used -host_seconds 7800.15 # Real time elapsed on the host -host_tick_rate 95165996 # Simulator tick rate (ticks/s) +host_inst_rate 254978 # Simulator instruction rate (inst/s) +host_mem_usage 190768 # Number of bytes of host memory used +host_seconds 6808.60 # Real time elapsed on the host +host_tick_rate 109025257 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 1736043781 # Number of instructions simulated sim_seconds 0.742309 # Number of seconds simulated @@ -133,17 +133,17 @@ system.cpu.decode.DECODE:RunCycles 549143104 # Nu system.cpu.decode.DECODE:SquashCycles 93084202 # Number of cycles decode is squashing system.cpu.decode.DECODE:SquashedInsts 1641 # Number of squashed instructions handled by decode system.cpu.decode.DECODE:UnblockCycles 5133136 # Number of cycles decode is unblocking -system.cpu.dtb.data_accesses 768331639 # DTB accesses +system.cpu.dtb.data_accesses 768331641 # DTB accesses system.cpu.dtb.data_acv 0 # DTB access violations -system.cpu.dtb.data_hits 752318838 # DTB hits +system.cpu.dtb.data_hits 752318840 # DTB hits system.cpu.dtb.data_misses 16012801 # DTB misses system.cpu.dtb.fetch_accesses 0 # ITB accesses system.cpu.dtb.fetch_acv 0 # ITB acv system.cpu.dtb.fetch_hits 0 # ITB hits system.cpu.dtb.fetch_misses 0 # ITB misses -system.cpu.dtb.read_accesses 566617551 # DTB read accesses +system.cpu.dtb.read_accesses 566617553 # DTB read accesses system.cpu.dtb.read_acv 0 # DTB read access violations -system.cpu.dtb.read_hits 557381525 # DTB read hits +system.cpu.dtb.read_hits 557381527 # DTB read hits system.cpu.dtb.read_misses 9236026 # DTB read misses system.cpu.dtb.write_accesses 201714088 # DTB write accesses system.cpu.dtb.write_acv 0 # DTB write access violations @@ -234,17 +234,17 @@ system.cpu.idleCycles 12319311 # To system.cpu.iew.EXEC:branches 282186314 # Number of branches executed system.cpu.iew.EXEC:nop 128796557 # number of nop insts executed system.cpu.iew.EXEC:rate 1.535065 # Inst execution rate -system.cpu.iew.EXEC:refs 769619324 # number of memory reference insts executed +system.cpu.iew.EXEC:refs 769619326 # number of memory reference insts executed system.cpu.iew.EXEC:stores 201925301 # Number of stores executed system.cpu.iew.EXEC:swp 0 # number of swp insts executed -system.cpu.iew.WB:consumers 1531990762 # num instructions consuming a value -system.cpu.iew.WB:count 2240290242 # cumulative count of insts written-back +system.cpu.iew.WB:consumers 1531990764 # num instructions consuming a value +system.cpu.iew.WB:count 2240290245 # cumulative count of insts written-back system.cpu.iew.WB:fanout 0.811831 # average fanout of values written-back system.cpu.iew.WB:penalized 0 # number of instrctions required to write to 'other' IQ system.cpu.iew.WB:penalized_rate 0 # fraction of instructions written-back that wrote to 'other' IQ -system.cpu.iew.WB:producers 1243717865 # num instructions producing a value +system.cpu.iew.WB:producers 1243717866 # num instructions producing a value system.cpu.iew.WB:rate 1.509000 # insts written-back per cycle -system.cpu.iew.WB:sent 2261678939 # cumulative count of insts sent to commit +system.cpu.iew.WB:sent 2261678943 # cumulative count of insts sent to commit system.cpu.iew.branchMispredicts 21342134 # Number of branch mispredicts detected at execute system.cpu.iew.iewBlockCycles 17373691 # Number of cycles IEW is blocking system.cpu.iew.iewDispLoadInsts 621608435 # Number of dispatched load instructions @@ -252,9 +252,9 @@ system.cpu.iew.iewDispNonSpecInsts 43 # Nu system.cpu.iew.iewDispSquashedInsts 22154841 # Number of squashed instructions skipped by dispatch system.cpu.iew.iewDispStoreInsts 234046222 # Number of dispatched store instructions system.cpu.iew.iewDispatchedInsts 2621719109 # Number of instructions dispatched to IQ -system.cpu.iew.iewExecLoadInsts 567694023 # Number of load instructions executed -system.cpu.iew.iewExecSquashedInsts 36858073 # Number of squashed instructions skipped in execute -system.cpu.iew.iewExecutedInsts 2278986827 # Number of executed instructions +system.cpu.iew.iewExecLoadInsts 567694025 # Number of load instructions executed +system.cpu.iew.iewExecSquashedInsts 36858071 # Number of squashed instructions skipped in execute +system.cpu.iew.iewExecutedInsts 2278986831 # Number of executed instructions system.cpu.iew.iewIQFullEvents 339653 # Number of times the IQ has become full, causing a stall system.cpu.iew.iewIdleCycles 0 # Number of cycles IEW is idle system.cpu.iew.iewLSQFullEvents 40208 # Number of times the LSQ has become full, causing a stall @@ -262,7 +262,7 @@ system.cpu.iew.iewSquashCycles 93084202 # Nu system.cpu.iew.iewUnblockCycles 758573 # Number of cycles IEW is unblocking system.cpu.iew.lsq.thread.0.blockedLoads 0 # Number of blocked loads due to partial load-store forwarding system.cpu.iew.lsq.thread.0.cacheBlocked 361643 # Number of times an access to memory failed due to the cache being blocked -system.cpu.iew.lsq.thread.0.forwLoads 33889596 # Number of loads that had data forwarded from stores +system.cpu.iew.lsq.thread.0.forwLoads 33889598 # Number of loads that had data forwarded from stores system.cpu.iew.lsq.thread.0.ignoredResponses 220185 # Number of memory responses ignored because the instruction is squashed system.cpu.iew.lsq.thread.0.invAddrLoads 0 # Number of loads ignored due to an invalid address system.cpu.iew.lsq.thread.0.invAddrSwpfs 0 # Number of software prefetches ignored due to an invalid address @@ -276,7 +276,7 @@ system.cpu.iew.predictedTakenIncorrect 20638338 # Nu system.cpu.ipc 1.169353 # IPC: Instructions Per Cycle system.cpu.ipc_total 1.169353 # IPC: Total IPC of All Threads system.cpu.iq.ISSUE:FU_type_0::No_OpClass 0 0.00% 0.00% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::IntAlu 1532920254 66.19% 66.19% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntAlu 1532920256 66.19% 66.19% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::IntMult 99 0.00% 66.19% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::IntDiv 0 0.00% 66.19% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::FloatAdd 234 0.00% 66.19% # Type of FU issued @@ -289,7 +289,7 @@ system.cpu.iq.ISSUE:FU_type_0::MemRead 577889733 24.95% 91.15% # Ty system.cpu.iq.ISSUE:FU_type_0::MemWrite 205034377 8.85% 100.00% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::IprAccess 0 0.00% 100.00% # Type of FU issued system.cpu.iq.ISSUE:FU_type_0::InstPrefetch 0 0.00% 100.00% # Type of FU issued -system.cpu.iq.ISSUE:FU_type_0::total 2315844900 # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::total 2315844902 # Type of FU issued system.cpu.iq.ISSUE:fu_busy_cnt 14393569 # FU busy when requested system.cpu.iq.ISSUE:fu_busy_rate 0.006215 # FU busy rate (busy events/executed inst) system.cpu.iq.ISSUE:fu_full::No_OpClass 0 0.00% 0.00% # attempts to use FU when none available @@ -311,9 +311,9 @@ system.cpu.iq.ISSUE:issued_per_cycle::mean 1.572944 # system.cpu.iq.ISSUE:issued_per_cycle::stdev 1.737325 # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::underflows 0 0.00% 0.00% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::0-1 577695763 39.24% 39.24% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::1-2 271543756 18.44% 57.68% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::1-2 271543755 18.44% 57.68% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::2-3 242868170 16.50% 74.18% # Number of insts issued each cycle -system.cpu.iq.ISSUE:issued_per_cycle::3-4 139713874 9.49% 83.67% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::3-4 139713875 9.49% 83.67% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::4-5 122021082 8.29% 91.95% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::5-6 69652698 4.73% 96.69% # Number of insts issued each cycle system.cpu.iq.ISSUE:issued_per_cycle::6-7 39670196 2.69% 99.38% # Number of insts issued each cycle @@ -325,12 +325,12 @@ system.cpu.iq.ISSUE:issued_per_cycle::max_value 8 system.cpu.iq.ISSUE:issued_per_cycle::total 1472299541 # Number of insts issued each cycle system.cpu.iq.ISSUE:rate 1.559892 # Inst issue rate system.cpu.iq.iqInstsAdded 2492922509 # Number of instructions added to the IQ (excludes non-spec) -system.cpu.iq.iqInstsIssued 2315844900 # Number of instructions issued +system.cpu.iq.iqInstsIssued 2315844902 # Number of instructions issued system.cpu.iq.iqNonSpecInstsAdded 43 # Number of non-speculative instructions added to the IQ system.cpu.iq.iqSquashedInstsExamined 739697610 # Number of squashed instructions iterated over during squash; mainly for profiling system.cpu.iq.iqSquashedInstsIssued 1501741 # Number of squashed instructions issued system.cpu.iq.iqSquashedNonSpecRemoved 14 # Number of squashed non-spec instructions that were removed -system.cpu.iq.iqSquashedOperandsExamined 329349456 # Number of squashed operands that are examined and possibly removed from graph +system.cpu.iq.iqSquashedOperandsExamined 329349452 # Number of squashed operands that are examined and possibly removed from graph system.cpu.itb.data_accesses 0 # DTB accesses system.cpu.itb.data_acv 0 # DTB access violations system.cpu.itb.data_hits 0 # DTB hits From 1b2d75d6d276f316b8c3f40fa93901ab6233128f Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:59 -0700 Subject: [PATCH 053/160] syscall: Addition of an ioctl command code for Power. --- src/arch/alpha/linux/linux.hh | 1 + src/arch/alpha/tru64/tru64.hh | 1 + src/arch/arm/linux/linux.hh | 1 + src/arch/mips/linux/linux.hh | 1 + src/sim/syscall_emul.hh | 1 + 5 files changed, 5 insertions(+) diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index e9947644cb..c728ce1fbe 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -105,6 +105,7 @@ class AlphaLinux : public Linux static const unsigned TIOCISATTY_ = 0x2000745e; static const unsigned TIOCGETS_ = 0x402c7413; static const unsigned TIOCGETA_ = 0x40127417; + static const unsigned TCSETAW_ = 0x80147419; // 2.6.15 kernel //@} /// For table(). diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh index 4ba35fc503..0ee12973cb 100644 --- a/src/arch/alpha/tru64/tru64.hh +++ b/src/arch/alpha/tru64/tru64.hh @@ -99,6 +99,7 @@ class AlphaTru64 : public Tru64 static const unsigned TIOCISATTY_ = 0x2000745e; static const unsigned TIOCGETS_ = 0x402c7413; static const unsigned TIOCGETA_ = 0x40127417; + static const unsigned TCSETAW_ = 0x80147419; //@} //@{ diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index b9b10a5936..f829dd7c65 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -86,6 +86,7 @@ class ArmLinux : public Linux static const unsigned TIOCISATTY_ = 0x2000745e; static const unsigned TIOCGETS_ = 0x402c7413; static const unsigned TIOCGETA_ = 0x40127417; + static const unsigned TCSETAW_ = 0x5407; // 2.6.15 kernel //@} /// For table(). diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index b30cca2fbc..a2418cfb65 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -100,6 +100,7 @@ class MipsLinux : public Linux static const unsigned TIOCISATTY_ = 0x5480; static const unsigned TIOCGETS_ = 0x540d; static const unsigned TIOCGETA_ = 0x7417; + static const unsigned TCSETAW_ = 0x5403; // 2.6.15 kernel //@} /// For table(). diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 21f8201c8d..0c51c7dec9 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -500,6 +500,7 @@ ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, case OS::TIOCGETC_: case OS::TIOCGETS_: case OS::TIOCGETA_: + case OS::TCSETAW_: return -ENOTTY; default: From 0fdfc82bde5b8975ee93d5da9c604ad9b99942e0 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Mon, 26 Oct 2009 17:06:32 -0700 Subject: [PATCH 054/160] fixed error message generation bug in SLICC ast files --- src/mem/slicc/ast/ChipComponentAccessAST.py | 4 ++-- src/mem/slicc/ast/MemberExprAST.py | 6 +++--- src/mem/slicc/ast/MethodCallExprAST.py | 12 ++++++------ src/mem/slicc/ast/ReturnStatementAST.py | 2 +- src/mem/slicc/ast/TypeFieldEnumAST.py | 6 +++--- src/mem/slicc/ast/TypeFieldMemberAST.py | 2 +- src/mem/slicc/ast/TypeFieldMethodAST.py | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.py b/src/mem/slicc/ast/ChipComponentAccessAST.py index 841220c948..bbb1b61e9c 100644 --- a/src/mem/slicc/ast/ChipComponentAccessAST.py +++ b/src/mem/slicc/ast/ChipComponentAccessAST.py @@ -85,8 +85,8 @@ class ChipMethodAccessAST(ChipComponentAccessAST): # Verify that this is a method of the object if not var.type.methodExist(methodId): - error("%s: Type '%s' does not have a method '%s'" % \ - ("Invalid method call", var.type, methodId)) + self.error("%s: Type '%s' does not have a method '%s'" % \ + ("Invalid method call", var.type, methodId)) expected_size = len(var.type.methodParamType(methodId)) if len(self.expr_vec) != expected_size: diff --git a/src/mem/slicc/ast/MemberExprAST.py b/src/mem/slicc/ast/MemberExprAST.py index 113bb188a4..c62e287416 100644 --- a/src/mem/slicc/ast/MemberExprAST.py +++ b/src/mem/slicc/ast/MemberExprAST.py @@ -47,9 +47,9 @@ class MemberExprAST(ExprAST): # Verify that this is a valid field name for this type if self.field not in return_type.data_members: - error("Invalid object field: " + - "Type '%s' does not have data member %s" % \ - (return_type, self.field)) + self.error("Invalid object field: " + + "Type '%s' does not have data member %s" % \ + (return_type, self.field)) # Return the type of the field return return_type.data_members[self.field].type diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py index ecfe43cdbd..d423ee4a7c 100644 --- a/src/mem/slicc/ast/MethodCallExprAST.py +++ b/src/mem/slicc/ast/MethodCallExprAST.py @@ -55,22 +55,22 @@ class MethodCallExprAST(ExprAST): # Verify that this is a method of the object if methodId not in obj_type.methods: - error("Invalid method call: Type '%s' does not have a method '%s'", - obj_type, methodId) + self.error("Invalid method call: Type '%s' does not have a method '%s'", + obj_type, methodId) if len(self.expr_ast_vec) != \ len(obj_type.methods[methodId].param_types): # Right number of parameters - error("Wrong number of parameters for function name: '%s', " + \ - "expected: , actual: ", proc_name, + self.error("Wrong number of parameters for function name: '%s', " + \ + "expected: , actual: ", proc_name, len(obj_type.methods[methodId].param_types), len(self.expr_ast_vec)) for actual_type, expected_type in \ zip(paramTypes, obj_type.methods[methodId].param_types): if actual_type != expected_type: - error("Type mismatch: expected: %s actual: %s", - expected_type, actual_type) + self.error("Type mismatch: expected: %s actual: %s", + expected_type, actual_type) # Return the return type of the method return obj_type.methods[methodId].return_type diff --git a/src/mem/slicc/ast/ReturnStatementAST.py b/src/mem/slicc/ast/ReturnStatementAST.py index 1d08a7234e..f1aff1c328 100644 --- a/src/mem/slicc/ast/ReturnStatementAST.py +++ b/src/mem/slicc/ast/ReturnStatementAST.py @@ -42,7 +42,7 @@ class ReturnStatementAST(StatementAST): # Is return valid here? if return_type is None: - error("Invalid 'return' statement") + self.error("Invalid 'return' statement") # The return type must match if return_type != actual_type: diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.py b/src/mem/slicc/ast/TypeFieldEnumAST.py index d068666ad4..138fff7930 100644 --- a/src/mem/slicc/ast/TypeFieldEnumAST.py +++ b/src/mem/slicc/ast/TypeFieldEnumAST.py @@ -41,19 +41,19 @@ class TypeFieldEnumAST(TypeFieldAST): def generate(self, type): # Add enumeration if not type.enumAdd(self.field_id, self.pairs_ast.pairs): - error("Duplicate enumeration: %s:%s" % (type, self.field_id)) + self.error("Duplicate enumeration: %s:%s" % (type, self.field_id)) # Fill machine info machine = self.symtab.state_machine if str(type) == "State": if not machine: - error("State declaration not part of a machine.") + self.error("State declaration not part of a machine.") s = State(self.symtab, self.field_id, self.location, self.pairs) machine.addState(s) if str(type) == "Event": if not machine: - error("Event declaration not part of a machine.") + self.error("Event declaration not part of a machine.") e = Event(self.symtab, self.field_id, self.location, self.pairs) machine.addEvent(e) diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.py b/src/mem/slicc/ast/TypeFieldMemberAST.py index 285d5b6225..a601536643 100644 --- a/src/mem/slicc/ast/TypeFieldMemberAST.py +++ b/src/mem/slicc/ast/TypeFieldMemberAST.py @@ -54,4 +54,4 @@ class TypeFieldMemberAST(TypeFieldAST): if not type.dataMemberAdd(self.field_id, field_type, self.pairs, init_code): - error("Duplicate data member: %s:%s" % (type_ptr, field_id)) + self.error("Duplicate data member: %s:%s" % (type_ptr, field_id)) diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.py b/src/mem/slicc/ast/TypeFieldMethodAST.py index 337b155972..2c8cf3f7be 100644 --- a/src/mem/slicc/ast/TypeFieldMethodAST.py +++ b/src/mem/slicc/ast/TypeFieldMethodAST.py @@ -47,4 +47,4 @@ class TypeFieldMethodAST(TypeFieldAST): # Add method if not type.methodAdd(self.ident, return_type, types): - error("Duplicate method: %s:%s()" % (type, self.ident)) + self.error("Duplicate method: %s:%s()" % (type, self.ident)) From 835a55e7f347697815fc43851b2dd5a8642d21c4 Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Tue, 27 Oct 2009 09:24:39 -0700 Subject: [PATCH 055/160] POWER: Add support for the Power ISA This adds support for the 32-bit, big endian Power ISA. This supports both integer and floating point instructions based on the Power ISA Book I v2.06. --- build_opts/POWER_SE | 3 + src/arch/isa_parser.py | 10 + src/arch/power/PowerTLB.py | 37 ++ src/arch/power/SConscript | 61 +++ src/arch/power/SConsopts | 33 ++ src/arch/power/faults.hh | 87 ++++ src/arch/power/insts/branch.cc | 169 +++++++ src/arch/power/insts/branch.hh | 241 +++++++++ src/arch/power/insts/condition.cc | 59 +++ src/arch/power/insts/condition.hh | 86 ++++ src/arch/power/insts/floating.cc | 60 +++ src/arch/power/insts/floating.hh | 153 ++++++ src/arch/power/insts/integer.cc | 170 +++++++ src/arch/power/insts/integer.hh | 176 +++++++ src/arch/power/insts/mem.cc | 74 +++ src/arch/power/insts/mem.hh | 91 ++++ src/arch/power/insts/misc.cc | 60 +++ src/arch/power/insts/misc.hh | 57 +++ src/arch/power/insts/static_inst.cc | 62 +++ src/arch/power/insts/static_inst.hh | 70 +++ src/arch/power/isa.hh | 115 +++++ src/arch/power/isa/bitfields.isa | 84 ++++ src/arch/power/isa/decoder.isa | 593 +++++++++++++++++++++++ src/arch/power/isa/formats/basic.isa | 103 ++++ src/arch/power/isa/formats/branch.isa | 222 +++++++++ src/arch/power/isa/formats/condition.isa | 47 ++ src/arch/power/isa/formats/formats.isa | 60 +++ src/arch/power/isa/formats/fp.isa | 132 +++++ src/arch/power/isa/formats/integer.isa | 369 ++++++++++++++ src/arch/power/isa/formats/mem.isa | 351 ++++++++++++++ src/arch/power/isa/formats/misc.isa | 61 +++ src/arch/power/isa/formats/unimp.isa | 146 ++++++ src/arch/power/isa/formats/unknown.isa | 87 ++++ src/arch/power/isa/formats/util.isa | 174 +++++++ src/arch/power/isa/includes.isa | 92 ++++ src/arch/power/isa/main.isa | 57 +++ src/arch/power/isa/operands.isa | 81 ++++ src/arch/power/isa_traits.hh | 75 +++ src/arch/power/linux/linux.cc | 79 +++ src/arch/power/linux/linux.hh | 148 ++++++ src/arch/power/linux/process.cc | 455 +++++++++++++++++ src/arch/power/linux/process.hh | 58 +++ src/arch/power/locked_mem.hh | 64 +++ src/arch/power/microcode_rom.hh | 45 ++ src/arch/power/miscregs.hh | 95 ++++ src/arch/power/mmaped_ipr.hh | 66 +++ src/arch/power/pagetable.cc | 82 ++++ src/arch/power/pagetable.hh | 158 ++++++ src/arch/power/predecoder.hh | 121 +++++ src/arch/power/process.cc | 288 +++++++++++ src/arch/power/process.hh | 59 +++ src/arch/power/registers.hh | 105 ++++ src/arch/power/remote_gdb.hh | 84 ++++ src/arch/power/stacktrace.hh | 148 ++++++ src/arch/power/tlb.cc | 322 ++++++++++++ src/arch/power/tlb.hh | 171 +++++++ src/arch/power/types.hh | 91 ++++ src/arch/power/utility.hh | 118 +++++ src/arch/power/vtophys.hh | 57 +++ src/base/loader/elf_object.cc | 13 + src/base/loader/object_file.hh | 3 +- src/cpu/BaseCPU.py | 11 + src/sim/process.cc | 18 +- 63 files changed, 7465 insertions(+), 2 deletions(-) create mode 100644 build_opts/POWER_SE create mode 100644 src/arch/power/PowerTLB.py create mode 100644 src/arch/power/SConscript create mode 100644 src/arch/power/SConsopts create mode 100644 src/arch/power/faults.hh create mode 100644 src/arch/power/insts/branch.cc create mode 100644 src/arch/power/insts/branch.hh create mode 100644 src/arch/power/insts/condition.cc create mode 100644 src/arch/power/insts/condition.hh create mode 100644 src/arch/power/insts/floating.cc create mode 100644 src/arch/power/insts/floating.hh create mode 100644 src/arch/power/insts/integer.cc create mode 100644 src/arch/power/insts/integer.hh create mode 100644 src/arch/power/insts/mem.cc create mode 100644 src/arch/power/insts/mem.hh create mode 100644 src/arch/power/insts/misc.cc create mode 100644 src/arch/power/insts/misc.hh create mode 100644 src/arch/power/insts/static_inst.cc create mode 100644 src/arch/power/insts/static_inst.hh create mode 100644 src/arch/power/isa.hh create mode 100644 src/arch/power/isa/bitfields.isa create mode 100644 src/arch/power/isa/decoder.isa create mode 100644 src/arch/power/isa/formats/basic.isa create mode 100644 src/arch/power/isa/formats/branch.isa create mode 100644 src/arch/power/isa/formats/condition.isa create mode 100644 src/arch/power/isa/formats/formats.isa create mode 100644 src/arch/power/isa/formats/fp.isa create mode 100644 src/arch/power/isa/formats/integer.isa create mode 100644 src/arch/power/isa/formats/mem.isa create mode 100644 src/arch/power/isa/formats/misc.isa create mode 100644 src/arch/power/isa/formats/unimp.isa create mode 100644 src/arch/power/isa/formats/unknown.isa create mode 100644 src/arch/power/isa/formats/util.isa create mode 100644 src/arch/power/isa/includes.isa create mode 100644 src/arch/power/isa/main.isa create mode 100644 src/arch/power/isa/operands.isa create mode 100644 src/arch/power/isa_traits.hh create mode 100644 src/arch/power/linux/linux.cc create mode 100644 src/arch/power/linux/linux.hh create mode 100644 src/arch/power/linux/process.cc create mode 100644 src/arch/power/linux/process.hh create mode 100644 src/arch/power/locked_mem.hh create mode 100644 src/arch/power/microcode_rom.hh create mode 100644 src/arch/power/miscregs.hh create mode 100644 src/arch/power/mmaped_ipr.hh create mode 100644 src/arch/power/pagetable.cc create mode 100644 src/arch/power/pagetable.hh create mode 100644 src/arch/power/predecoder.hh create mode 100644 src/arch/power/process.cc create mode 100644 src/arch/power/process.hh create mode 100644 src/arch/power/registers.hh create mode 100644 src/arch/power/remote_gdb.hh create mode 100644 src/arch/power/stacktrace.hh create mode 100644 src/arch/power/tlb.cc create mode 100644 src/arch/power/tlb.hh create mode 100644 src/arch/power/types.hh create mode 100644 src/arch/power/utility.hh create mode 100644 src/arch/power/vtophys.hh diff --git a/build_opts/POWER_SE b/build_opts/POWER_SE new file mode 100644 index 0000000000..d76ca7180d --- /dev/null +++ b/build_opts/POWER_SE @@ -0,0 +1,3 @@ +TARGET_ISA = 'power' +FULL_SYSTEM = 0 +CPU_MODELS = 'AtomicSimpleCPU,TimingSimpleCPU,O3CPU' diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index f001eff41c..e3da240d25 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -1465,6 +1465,16 @@ class MemOperand(Operand): def makeAccSize(self): return self.size +class PCOperand(Operand): + def makeConstructor(self): + return '' + + def makeRead(self): + return '%s = xc->readPC();\n' % self.base_name + + def makeWrite(self): + return 'xc->setPC(%s);\n' % self.base_name + class UPCOperand(Operand): def makeConstructor(self): return '' diff --git a/src/arch/power/PowerTLB.py b/src/arch/power/PowerTLB.py new file mode 100644 index 0000000000..36dff53338 --- /dev/null +++ b/src/arch/power/PowerTLB.py @@ -0,0 +1,37 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 The University of Edinburgh +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Timothy M. Jones + +from m5.SimObject import SimObject +from m5.params import * + +class PowerTLB(SimObject): + type = 'PowerTLB' + cxx_class = 'PowerISA::TLB' + size = Param.Int(64, "TLB size") diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript new file mode 100644 index 0000000000..1fb36eaab7 --- /dev/null +++ b/src/arch/power/SConscript @@ -0,0 +1,61 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 The University of Edinburgh +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Timothy M. Jones + +Import('*') + +if env['TARGET_ISA'] == 'power': +# Workaround for bug in SCons version > 0.97d20071212 +# Scons bug id: 2006 M5 Bug id: 308 + Dir('isa/formats') + Source('insts/branch.cc') + Source('insts/mem.cc') + Source('insts/integer.cc') + Source('insts/floating.cc') + Source('insts/condition.cc') + Source('insts/static_inst.cc') + Source('pagetable.cc') + Source('tlb.cc') + + SimObject('PowerTLB.py') + TraceFlag('Power') + + if not env['FULL_SYSTEM']: + Source('process.cc') + Source('linux/linux.cc') + Source('linux/process.cc') + + # Add in files generated by the ISA description. + isa_desc_files = env.ISADesc('isa/main.isa') + + # Only non-header files need to be compiled. + for f in isa_desc_files: + if not f.path.endswith('.hh'): + Source(f) + diff --git a/src/arch/power/SConsopts b/src/arch/power/SConsopts new file mode 100644 index 0000000000..d762c2d581 --- /dev/null +++ b/src/arch/power/SConsopts @@ -0,0 +1,33 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 The University of Edinburgh +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Timothy M. Jones + +Import('*') + +all_isa_list.append('power') diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh new file mode 100644 index 0000000000..eadcb79006 --- /dev/null +++ b/src/arch/power/faults.hh @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_FAULTS_HH__ +#define __ARCH_POWER_FAULTS_HH__ + +#include "sim/faults.hh" + +namespace PowerISA +{ + +class PowerFault : public FaultBase +{ + protected: + FaultName _name; + + PowerFault(FaultName name) + : _name(name) + { + } + + FaultName + name() const + { + return _name; + } +}; + + +class UnimplementedOpcodeFault : public PowerFault +{ + public: + UnimplementedOpcodeFault() + : PowerFault("Unimplemented Opcode") + { + } +}; + + +class MachineCheckFault : public PowerFault +{ + public: + MachineCheckFault() + : PowerFault("Machine Check") + { + } +}; + + +static inline Fault +genMachineCheckFault() +{ + return new MachineCheckFault(); +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_FAULTS_HH__ diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc new file mode 100644 index 0000000000..3f4346c97e --- /dev/null +++ b/src/arch/power/insts/branch.cc @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/branch.hh" +#include "base/loader/symtab.hh" + +using namespace PowerISA; + +const std::string & +PCDependentDisassembly::disassemble(Addr pc, const SymbolTable *symtab) const +{ + if (!cachedDisassembly || + pc != cachedPC || symtab != cachedSymtab) + { + if (cachedDisassembly) + delete cachedDisassembly; + + cachedDisassembly = + new std::string(generateDisassembly(pc, symtab)); + cachedPC = pc; + cachedSymtab = symtab; + } + + return *cachedDisassembly; +} + +Addr +BranchPCRel::branchTarget(Addr pc) const +{ + return (uint32_t)(pc + disp); +} + +std::string +BranchPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + Addr target = pc + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); +} + +Addr +BranchNonPCRel::branchTarget(Addr pc) const +{ + return targetAddr; +} + +std::string +BranchNonPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + std::string str; + if (symtab && symtab->findSymbol(targetAddr, str)) + ss << str; + else + ccprintf(ss, "0x%x", targetAddr); + + return ss.str(); +} + +Addr +BranchPCRelCond::branchTarget(Addr pc) const +{ + return (uint32_t)(pc + disp); +} + +std::string +BranchPCRelCond::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ss << bo << ", " << bi << ", "; + + Addr target = pc + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); +} + +Addr +BranchNonPCRelCond::branchTarget(Addr pc) const +{ + return targetAddr; +} + +std::string +BranchNonPCRelCond::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ss << bo << ", " << bi << ", "; + + std::string str; + if (symtab && symtab->findSymbol(targetAddr, str)) + ss << str; + else + ccprintf(ss, "0x%x", targetAddr); + + return ss.str(); +} + +Addr +BranchRegCond::branchTarget(ThreadContext *tc) const +{ + uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1]); + return (regVal & 0xfffffffc); +} + +std::string +BranchRegCond::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ss << bo << ", " << bi << ", "; + + return ss.str(); +} diff --git a/src/arch/power/insts/branch.hh b/src/arch/power/insts/branch.hh new file mode 100644 index 0000000000..dd00e42c3f --- /dev/null +++ b/src/arch/power/insts/branch.hh @@ -0,0 +1,241 @@ +/* Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_BRANCH_HH__ +#define __ARCH_POWER_INSTS_BRANCH_HH__ + +#include "arch/power/insts/static_inst.hh" + +namespace PowerISA +{ + +/** + * Base class for instructions whose disassembly is not purely a + * function of the machine instruction (i.e., it depends on the + * PC). This class overrides the disassemble() method to check + * the PC and symbol table values before re-using a cached + * disassembly string. This is necessary for branches and jumps, + * where the disassembly string includes the target address (which + * may depend on the PC and/or symbol table). + */ +class PCDependentDisassembly : public PowerStaticInst +{ + protected: + /// Cached program counter from last disassembly + mutable Addr cachedPC; + /// Cached symbol table pointer from last disassembly + mutable const SymbolTable *cachedSymtab; + + /// Constructor + PCDependentDisassembly(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + cachedPC(0), cachedSymtab(0) + { + } + + const std::string & + disassemble(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for unconditional, PC-relative branches. + */ +class BranchPCRel : public PCDependentDisassembly +{ + protected: + + /// Displacement + uint32_t disp; + + /// Constructor. + BranchPCRel(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(machInst.li << 2) + { + // If bit 26 is 1 then sign extend + if (disp & 0x2000000) { + disp |= 0xfc000000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for unconditional, non PC-relative branches. + */ +class BranchNonPCRel : public PCDependentDisassembly +{ + protected: + + /// Target address + uint32_t targetAddr; + + /// Constructor. + BranchNonPCRel(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + targetAddr(machInst.li << 2) + { + // If bit 26 is 1 then sign extend + if (targetAddr & 0x2000000) { + targetAddr |= 0xfc000000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for conditional branches. + */ +class BranchCond : public PCDependentDisassembly +{ + protected: + + /// Fields needed for conditions + uint32_t bo; + uint32_t bi; + + /// Constructor. + BranchCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + bo(machInst.bo), + bi(machInst.bi) + { + } + + inline bool + ctrOk(uint32_t& ctr) const + { + bool ctr_ok; + if (bo & 4) { + ctr_ok = true; + } else { + ctr--; + if (ctr != 0) { + ctr_ok = ((bo & 2) == 0); + } else { + ctr_ok = ((bo & 2) != 0); + } + } + return ctr_ok; + } + + inline bool + condOk(uint32_t cr) const + { + bool cond_ok; + if (bo & 16) { + cond_ok = true; + } else { + cond_ok = (((cr >> (31 - bi)) & 1) == ((bo >> 3) & 1)); + } + return cond_ok; + } +}; + +/** + * Base class for conditional, PC-relative branches. + */ +class BranchPCRelCond : public BranchCond +{ + protected: + + /// Displacement + uint32_t disp; + + /// Constructor. + BranchPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : BranchCond(mnem, _machInst, __opClass), + disp(machInst.bd << 2) + { + // If bit 16 is 1 then sign extend + if (disp & 0x8000) { + disp |= 0xffff0000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for conditional, non PC-relative branches. + */ +class BranchNonPCRelCond : public BranchCond +{ + protected: + + /// Target address + uint32_t targetAddr; + + /// Constructor. + BranchNonPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : BranchCond(mnem, _machInst, __opClass), + targetAddr(machInst.bd << 2) + { + // If bit 16 is 1 then sign extend + if (targetAddr & 0x8000) { + targetAddr |= 0xffff0000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for conditional, register-based branches + */ +class BranchRegCond : public BranchCond +{ + protected: + + /// Constructor. + BranchRegCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : BranchCond(mnem, _machInst, __opClass) + { + } + + Addr branchTarget(ThreadContext *tc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_BRANCH_HH__ diff --git a/src/arch/power/insts/condition.cc b/src/arch/power/insts/condition.cc new file mode 100644 index 0000000000..0a942a982e --- /dev/null +++ b/src/arch/power/insts/condition.cc @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/condition.hh" + +using namespace PowerISA; + +std::string +CondLogicOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Format is bt, ba, bb + ss << bt << ", " << ba << ", " << bb; + + return ss.str(); +} + +std::string +CondMoveOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Format is bf, bfa + ss << bf << ", " << bfa; + + return ss.str(); +} diff --git a/src/arch/power/insts/condition.hh b/src/arch/power/insts/condition.hh new file mode 100644 index 0000000000..a23667d9ec --- /dev/null +++ b/src/arch/power/insts/condition.hh @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_CONDITION_HH__ +#define __ARCH_POWER_INSTS_CONDITION_HH__ + +#include "arch/power/insts/static_inst.hh" +#include "base/cprintf.hh" + +namespace PowerISA +{ + +/** + * Class for condition register logical operations. + */ +class CondLogicOp : public PowerStaticInst +{ + protected: + + uint32_t ba; + uint32_t bb; + uint32_t bt; + + /// Constructor + CondLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + ba(machInst.ba), + bb(machInst.bb), + bt(machInst.bt) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Class for condition register move operations. + */ +class CondMoveOp : public PowerStaticInst +{ + protected: + + uint32_t bf; + uint32_t bfa; + + /// Constructor + CondMoveOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + bf(machInst.bf), + bfa(machInst.bfa) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_CONDITION_HH__ diff --git a/src/arch/power/insts/floating.cc b/src/arch/power/insts/floating.cc new file mode 100644 index 0000000000..f5c34ee2ad --- /dev/null +++ b/src/arch/power/insts/floating.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/floating.hh" + +using namespace PowerISA; + +std::string +FloatOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the (possibly) two source registers + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); +} diff --git a/src/arch/power/insts/floating.hh b/src/arch/power/insts/floating.hh new file mode 100644 index 0000000000..2b26684094 --- /dev/null +++ b/src/arch/power/insts/floating.hh @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + * Korey Sewell + */ + +#ifndef __ARCH_POWER_INSTS_FLOATING_HH__ +#define __ARCH_POWER_INSTS_FLOATING_HH__ + +#include "arch/power/insts/static_inst.hh" +#include "base/cprintf.hh" +#include "base/bitfield.hh" + +namespace PowerISA +{ + +/** + * Base class for floating point operations. + */ +class FloatOp : public PowerStaticInst +{ + protected: + + bool rcSet; + + /// Constructor + FloatOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass) + { + } + + // Test for NaN (maximum biased exponent & non-zero fraction) + inline bool + isNan(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 23) == 0xFF) && bits(val_bits, 22, 0)); + } + + inline bool + isNan(uint64_t val_bits) const + { + return ((bits(val_bits, 62, 52) == 0x7FF) && bits(val_bits, 51, 0)); + } + + inline bool + isNan(float val) const + { + void *val_ptr = &val; + uint32_t val_bits = *(uint32_t *) val_ptr; + return isNan(val_bits); + } + + inline bool + isNan(double val) const + { + void *val_ptr = &val; + uint64_t val_bits = *(uint64_t *) val_ptr; + return isNan(val_bits); + } + + // Test for SNaN (NaN with high order bit of fraction set to 0) + inline bool + isSnan(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 22) == 0x1FE) && bits(val_bits, 22, 0)); + } + + // Test for QNaN (NaN with high order bit of fraction set to 1) + inline bool + isQnan(uint32_t val_bits) const + { + return (bits(val_bits, 30, 22) == 0x1FF); + } + + // Test for infinity (maximum biased exponent and zero fraction) + inline bool + isInfinity(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 23) == 0xFF) && !bits(val_bits, 22, 0)); + } + + // Test for normalized numbers (biased exponent in the range 1 to 254) + inline bool + isNormalized(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 23) != 0xFF) && bits(val_bits, 22, 0)); + } + + // Test for denormalized numbers (biased exponent of zero and + // non-zero fraction) + inline bool + isDenormalized(uint32_t val_bits) const + { + return (!bits(val_bits, 30, 23) && bits(val_bits, 22, 0)); + } + + // Test for zero (biased exponent of zero and fraction of zero) + inline bool + isZero(uint32_t val_bits) const + { + return (!bits(val_bits, 30, 23) && !bits(val_bits, 22, 0)); + } + + // Test for negative + inline bool + isNegative(uint32_t val_bits) const + { + return (bits(val_bits, 31)); + } + + // Compute the CR field + inline uint32_t + makeCRField(double a, double b) const + { + uint32_t c = 0; + if (isNan(a) || isNan(b)) { c = 0x1; } + else if (a < b) { c = 0x8; } + else if (a > b) { c = 0x4; } + else { c = 0x2; } + return c; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_FLOATING_HH__ diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc new file mode 100644 index 0000000000..1f81a15dc7 --- /dev/null +++ b/src/arch/power/insts/integer.cc @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/integer.hh" + +using namespace std; +using namespace PowerISA; + +string +IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + bool printDest = true; + bool printSrcs = true; + bool printSecondSrc = true; + + // Generate the correct mnemonic + string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("or") && _srcRegIdx[0] == _srcRegIdx[1]) { + myMnemonic = "mr"; + printSecondSrc = false; + } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) { + printDest = false; + } else if (!myMnemonic.compare("mflr")) { + printSrcs = false; + } + + // Additional characters depending on isa bits being set + if (oeSet) myMnemonic = myMnemonic + "o"; + if (rcSet) myMnemonic = myMnemonic + "."; + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (_numDestRegs > 0 && printDest) { + printReg(ss, _destRegIdx[0]); + } + + // Print the (possibly) two source registers + if (_numSrcRegs > 0 && printSrcs) { + if (_numDestRegs > 0 && printDest) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + if (_numSrcRegs > 1 && printSecondSrc) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); +} + + +string +IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + + // Generate the correct mnemonic + string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("addi") && _numSrcRegs == 0) { + myMnemonic = "li"; + } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) { + myMnemonic = "lis"; + } + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + } + + // Print the immediate value last + ss << ", " << (int32_t)imm; + + return ss.str(); +} + + +string +IntShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + } + + // Print the shift + ss << ", " << sh; + + return ss.str(); +} + + +string +IntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + } + + // Print the shift, mask begin and mask end + ss << ", " << sh << ", " << mb << ", " << me; + + return ss.str(); +} diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh new file mode 100644 index 0000000000..b4b96d5dc5 --- /dev/null +++ b/src/arch/power/insts/integer.hh @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_INTEGER_HH__ +#define __ARCH_POWER_INSTS_INTEGER_HH__ + +#include "arch/power/insts/static_inst.hh" +#include "base/cprintf.hh" +#include "base/bitfield.hh" + +namespace PowerISA +{ + +/** + * We provide a base class for integer operations and then inherit for + * several other classes. These specialise for instructions using immediate + * values and also rotate instructions. We also need to have versions that + * consider the Rc and OE bits. + */ + +/** + * Base class for integer operations. + */ +class IntOp : public PowerStaticInst +{ + protected: + + bool rcSet; + bool oeSet; + + // Needed for srawi only + uint32_t sh; + + /// Constructor + IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + rcSet(false), oeSet(false) + { + } + + /* Compute the CR (condition register) field using signed comparison */ + inline uint32_t + makeCRField(int32_t a, int32_t b, uint32_t xerSO) const + { + uint32_t c = xerSO; + + /* We've pre-shifted the immediate values here */ + if (a < b) { c += 0x8; } + else if (a > b) { c += 0x4; } + else { c += 0x2; } + return c; + } + + /* Compute the CR (condition register) field using unsigned comparison */ + inline uint32_t + makeCRField(uint32_t a, uint32_t b, uint32_t xerSO) const + { + uint32_t c = xerSO; + + /* We've pre-shifted the immediate values here */ + if (a < b) { c += 0x8; } + else if (a > b) { c += 0x4; } + else { c += 0x2; } + return c; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for integer immediate (signed and unsigned) operations. + */ +class IntImmOp : public IntOp +{ + protected: + + int32_t imm; + uint32_t uimm; + + /// Constructor + IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntOp(mnem, _machInst, __opClass), + imm(sext<16>(machInst.si)), + uimm(machInst.si) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for integer operations with a shift. + */ +class IntShiftOp : public IntOp +{ + protected: + + uint32_t sh; + + /// Constructor + IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntOp(mnem, _machInst, __opClass), + sh(machInst.sh) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for integer rotate operations. + */ +class IntRotateOp : public IntShiftOp +{ + protected: + + uint32_t mb; + uint32_t me; + uint32_t fullMask; + + /// Constructor + IntRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntShiftOp(mnem, _machInst, __opClass), + mb(machInst.mb), + me(machInst.me) + { + if (me >= mb) { + fullMask = mask(31 - mb, 31 - me); + } else { + fullMask = ~mask(31 - (me + 1), 31 - (mb - 1)); + } + } + + uint32_t + rotateValue(uint32_t rs, uint32_t shift) const + { + uint32_t n = shift & 31; + return (rs << n) | (rs >> (32 - n)); + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_INTEGER_HH__ diff --git a/src/arch/power/insts/mem.cc b/src/arch/power/insts/mem.cc new file mode 100644 index 0000000000..447efa2f45 --- /dev/null +++ b/src/arch/power/insts/mem.cc @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/mem.hh" +#include "base/loader/symtab.hh" + +using namespace PowerISA; + +std::string +MemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + return csprintf("%-10s", mnemonic); +} + +std::string +MemDispOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the destination only for a load + if (!flags[IsStore]) { + if (_numDestRegs > 0) { + + // If the instruction updates the source register with the + // EA, then this source register is placed in position 0, + // therefore we print the last destination register. + printReg(ss, _destRegIdx[_numDestRegs-1]); + } + } + + // Print the data register for a store + else { + printReg(ss, _srcRegIdx[1]); + } + + // Print the displacement + ss << ", " << (int32_t)disp; + + // Print the address register + ss << "("; + printReg(ss, _srcRegIdx[0]); + ss << ")"; + + return ss.str(); +} diff --git a/src/arch/power/insts/mem.hh b/src/arch/power/insts/mem.hh new file mode 100644 index 0000000000..329dafe570 --- /dev/null +++ b/src/arch/power/insts/mem.hh @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_MEM_HH__ +#define __ARCH_POWER_MEM_HH__ + +#include "arch/power/insts/static_inst.hh" + +namespace PowerISA +{ + +/** + * Base class for memory operations. + */ +class MemOp : public PowerStaticInst +{ + protected: + + /// Memory request flags. See mem_req_base.hh. + unsigned memAccessFlags; + /// Pointer to EAComp object. + const StaticInstPtr eaCompPtr; + /// Pointer to MemAcc object. + const StaticInstPtr memAccPtr; + + /// Constructor + MemOp(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : PowerStaticInst(mnem, _machInst, __opClass), + memAccessFlags(0), + eaCompPtr(_eaCompPtr), + memAccPtr(_memAccPtr) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for memory operations with displacement. + */ +class MemDispOp : public MemOp +{ + protected: + + int16_t disp; + + /// Constructor + MemDispOp(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : MemOp(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), + disp(machInst.d) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_MEM_HH__ diff --git a/src/arch/power/insts/misc.cc b/src/arch/power/insts/misc.cc new file mode 100644 index 0000000000..913030b612 --- /dev/null +++ b/src/arch/power/insts/misc.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/misc.hh" + +using namespace PowerISA; + +std::string +MiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the (possibly) two source registers + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); +} diff --git a/src/arch/power/insts/misc.hh b/src/arch/power/insts/misc.hh new file mode 100644 index 0000000000..dd4941b934 --- /dev/null +++ b/src/arch/power/insts/misc.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_MISC_HH__ +#define __ARCH_POWER_INSTS_MISC_HH__ + +#include "arch/power/insts/static_inst.hh" + +namespace PowerISA +{ + +/** + * Class for misc operations. + */ +class MiscOp : public PowerStaticInst +{ + protected: + + /// Constructor + MiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_MISC_HH__ diff --git a/src/arch/power/insts/static_inst.cc b/src/arch/power/insts/static_inst.cc new file mode 100644 index 0000000000..1982744bf6 --- /dev/null +++ b/src/arch/power/insts/static_inst.cc @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/static_inst.hh" + +using namespace PowerISA; + +void +PowerStaticInst::printReg(std::ostream &os, int reg) const +{ + if (reg < FP_Base_DepTag) { + ccprintf(os, "r%d", reg); + } else if (reg < Ctrl_Base_DepTag) { + ccprintf(os, "f%d", reg - FP_Base_DepTag); + } else { + switch (reg - Ctrl_Base_DepTag) { + case 0: ccprintf(os, "cr"); break; + case 1: ccprintf(os, "xer"); break; + case 2: ccprintf(os, "lr"); break; + case 3: ccprintf(os, "ctr"); break; + default: ccprintf(os, "unknown_reg"); + } + } +} + +std::string +PowerStaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + return ss.str(); +} diff --git a/src/arch/power/insts/static_inst.hh b/src/arch/power/insts/static_inst.hh new file mode 100644 index 0000000000..399e753716 --- /dev/null +++ b/src/arch/power/insts/static_inst.hh @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_STATICINST_HH__ +#define __ARCH_POWER_INSTS_STATICINST_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +namespace PowerISA +{ + +class PowerStaticInst : public StaticInst +{ + protected: + + // Constructor + PowerStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + // Insert a condition value into a CR (condition register) field + inline uint32_t + insertCRField(uint32_t cr, uint32_t bf, uint32_t value) const + { + uint32_t bits = value << ((7 - bf) * 4); + uint32_t mask = ~(0xf << ((7 - bf) * 4)); + return (cr & mask) | bits; + } + + /// Print a register name for disassembly given the unique + /// dependence tag number (FP or int). + void + printReg(std::ostream &os, int reg) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_STATICINST_HH__ diff --git a/src/arch/power/isa.hh b/src/arch/power/isa.hh new file mode 100644 index 0000000000..ba1b5018d4 --- /dev/null +++ b/src/arch/power/isa.hh @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2009 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_ISA_HH__ +#define __ARCH_POWER_ISA_HH__ + +#include "arch/power/registers.hh" +#include "arch/power/types.hh" +#include "base/misc.hh" + +class ThreadContext; +class Checkpoint; +class EventManager; + +namespace PowerISA +{ + +class ISA +{ + protected: + MiscReg dummy; + MiscReg miscRegs[NumMiscRegs]; + + public: + void + clear() + { + } + + MiscReg + readMiscRegNoEffect(int misc_reg) + { + fatal("Power does not currently have any misc regs defined\n"); + return dummy; + } + + MiscReg + readMiscReg(int misc_reg, ThreadContext *tc) + { + fatal("Power does not currently have any misc regs defined\n"); + return dummy; + } + + void + setMiscRegNoEffect(int misc_reg, const MiscReg &val) + { + fatal("Power does not currently have any misc regs defined\n"); + } + + void + setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) + { + fatal("Power does not currently have any misc regs defined\n"); + } + + int + flattenIntIndex(int reg) + { + return reg; + } + + int + flattenFloatIndex(int reg) + { + return reg; + } + + void + serialize(EventManager *em, std::ostream &os) + { + } + + void + unserialize(EventManager *em, Checkpoint *cp, const std::string §ion) + { + } + + ISA() + { + clear(); + } +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_ISA_HH__ diff --git a/src/arch/power/isa/bitfields.isa b/src/arch/power/isa/bitfields.isa new file mode 100644 index 0000000000..8cd323ad5a --- /dev/null +++ b/src/arch/power/isa/bitfields.isa @@ -0,0 +1,84 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Bitfield definitions. +// +// The endianness is the opposite to what's used here, so things +// are reversed sometimes. Not sure of a fix to this though... + +// Opcode fields +def bitfield OPCODE <31:26>; +def bitfield X_XO <10:0>; +def bitfield XO_XO <10:1>; +def bitfield A_XO <5:1>; + +// Register fields +def bitfield RA <20:16>; +def bitfield RB <15:11>; +def bitfield RS <25:21>; +def bitfield RT <25:21>; +def bitfield FRA <20:16>; +def bitfield FRB <15:11>; +def bitfield FRC <10:6>; +def bitfield FRS <25:21>; +def bitfield FRT <25:21>; + +// The record bit can be in two positions +// Used to enable setting of the condition register +def bitfield RC31 <0>; +def bitfield RC21 <10>; + +// Used to enable setting of the overflow flags +def bitfield OE <10>; + +// SPR field for mtspr instruction +def bitfield SPR <20:11>; + +// FXM field for mtcrf instruction +def bitfield FXM <19:12>; + +// Branch fields +def bitfield LK <0>; +def bitfield AA <1>; + +// Specifies a CR or FPSCR field +def bitfield BF <25:23>; + +// Fields for FPSCR manipulation instructions +def bitfield FLM <24:17>; +def bitfield L <25>; +def bitfield W <16>; +// Named so to avoid conflicts with range.hh +def bitfield U_FIELD <15:12>; + +// Field for specifying a bit in CR or FPSCR +def bitfield BT <25:21>; diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa new file mode 100644 index 0000000000..3252ff14a4 --- /dev/null +++ b/src/arch/power/isa/decoder.isa @@ -0,0 +1,593 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// The actual Power ISA decoder +// ------------------------------ +// +// I've used the Power ISA Book I v2.06 for instruction formats, +// opcode numbers, register names, etc. +// +decode OPCODE default Unknown::unknown() { + + format IntImmOp { + 10: cmpli({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra, (uint32_t)uimm, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + 11: cmpi({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra.sw, (int32_t)imm, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + } + + // Some instructions use bits 21 - 30, others 22 - 30. We have to use + // the larger size to account for all opcodes. For those that use the + // smaller value, the OE bit is bit 21. Therefore, we have two versions + // of each instruction: 1 with OE set, the other without. For an + // example see 'add' and 'addo'. + 31: decode XO_XO { + + // These instructions can all be reduced to the form + // Rt = src1 + src2 [+ CA], therefore we just give src1 and src2 + // (and, if necessary, CA) definitions and let the python script + // deal with setting things up correctly. We also give flags to + // say which control registers to set. + format IntSumOp { + 266: add({{ Ra }}, {{ Rb }}); + 40: subf({{ ~Ra }}, {{ Rb }}, {{ 1 }}); + 10: addc({{ Ra }}, {{ Rb }}, + computeCA = true); + 8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }}, + true); + 104: neg({{ ~Ra }}, {{ 1 }}); + 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }}, + true); + 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, + true); + 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }}, + true); + 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, + true); + 202: addze({{ Ra }}, {{ xer.ca }}, + computeCA = true); + 200: subfze({{ ~Ra }}, {{ xer.ca }}, + computeCA = true); + } + + // Arithmetic instructions all use source registers Ra and Rb, + // with destination register Rt. + format IntArithOp { + 75: mulhw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod >> 32; }}); + 11: mulhwu({{ uint64_t prod = Ra.uq * Rb.uq; Rt = prod >> 32; }}); + 235: mullw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod; }}); + 747: mullwo({{ int64_t src1 = Ra.sq; int64_t src2 = Rb; int64_t prod = src1 * src2; Rt = prod; }}, + true); + + 491: divw({{ + int32_t src1 = Ra.sw; + int32_t src2 = Rb.sw; + if ((src1 != 0x80000000 || src2 != 0xffffffff) + && src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + } + }}); + + 1003: divwo({{ + int32_t src1 = Ra.sw; + int32_t src2 = Rb.sw; + if ((src1 != 0x80000000 || src2 != 0xffffffff) + && src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + divSetOV = true; + } + }}, + true); + + 459: divwu({{ + uint32_t src1 = Ra.sw; + uint32_t src2 = Rb.sw; + if (src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + } + }}); + + 971: divwuo({{ + uint32_t src1 = Ra.sw; + uint32_t src2 = Rb.sw; + if (src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + divSetOV = true; + } + }}, + true); + } + + // Integer logic instructions use source registers Rs and Rb, + // with destination register Ra. + format IntLogicOp { + 28: and({{ Ra = Rs & Rb; }}); + 316: xor({{ Ra = Rs ^ Rb; }}); + 476: nand({{ Ra = ~(Rs & Rb); }}); + 444: or({{ Ra = Rs | Rb; }}); + 124: nor({{ Ra = ~(Rs | Rb); }}); + 60: andc({{ Ra = Rs & ~Rb; }}); + 954: extsb({{ Ra = sext<8>(Rs); }}); + 284: eqv({{ Ra = ~(Rs ^ Rb); }}); + 412: orc({{ Ra = Rs | ~Rb; }}); + 922: extsh({{ Ra = sext<16>(Rs); }}); + 26: cntlzw({{ Ra = Rs == 0 ? 32 : 31 - findMsbSet(Rs); }}); + 508: cmpb({{ + uint32_t val = 0; + for (int n = 0; n < 32; n += 8) { + if(bits(Rs, n, n+7) == bits(Rb, n, n+7)) { + val = insertBits(val, n, n+7, 0xff); + } + } + Ra = val; + }}); + + 24: slw({{ + if (Rb & 0x20) { + Ra = 0; + } else { + Ra = Rs << (Rb & 0x1f); + } + }}); + + 536: srw({{ + if (Rb & 0x20) { + Ra = 0; + } else { + Ra = Rs >> (Rb & 0x1f); + } + }}); + + 792: sraw({{ + bool shiftSetCA = false; + int32_t s = Rs; + if (Rb == 0) { + Ra = Rs; + shiftSetCA = true; + } else if (Rb & 0x20) { + if (s < 0) { + Ra = (uint32_t)-1; + if (s & 0x7fffffff) { + shiftSetCA = true; + } else { + shiftSetCA = false; + } + } else { + Ra = 0; + shiftSetCA = false; + } + } else { + Ra = s >> (Rb & 0x1f); + if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) { + shiftSetCA = true; + } else { + shiftSetCA = false; + } + } + Xer xer1 = XER; + if (shiftSetCA) { + xer1.ca = 1; + } else { + xer1.ca = 0; + } + XER = xer1; + }}); + } + + // Integer logic instructions with a shift value. + format IntShiftOp { + 824: srawi({{ + bool shiftSetCA = false; + if (sh == 0) { + Ra = Rs; + shiftSetCA = false; + } else { + int32_t s = Rs; + Ra = s >> sh; + if (s < 0 && (s << (32 - sh)) != 0) { + shiftSetCA = true; + } else { + shiftSetCA = false; + } + } + Xer xer1 = XER; + if (shiftSetCA) { + xer1.ca = 1; + } else { + xer1.ca = 0; + } + XER = xer1; + }}); + } + + // Generic integer format instructions. + format IntOp { + 0: cmp({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra.sw, Rb.sw, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + 32: cmpl({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra, Rb, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + 144: mtcrf({{ + uint32_t mask = 0; + for (int i = 0; i < 8; ++i) { + if (((FXM >> i) & 0x1) == 0x1) { + mask |= 0xf << (4 * i); + } + } + CR = (Rs & mask) | (CR & ~mask); + }}); + 19: mfcr({{ Rt = CR; }}); + 339: decode SPR { + 0x20: mfxer({{ Rt = XER; }}); + 0x100: mflr({{ Rt = LR; }}); + 0x120: mfctr({{ Rt = CTR; }}); + } + 467: decode SPR { + 0x20: mtxer({{ XER = Rs; }}); + 0x100: mtlr({{ LR = Rs; }}); + 0x120: mtctr({{ CTR = Rs; }}); + } + } + + // All loads with an index register. The non-update versions + // all use the value 0 if Ra == R0, not the value contained in + // R0. Others update Ra with the effective address. In all cases, + // Ra and Rb are source registers, Rt is the destintation. + format LoadIndexOp { + 87: lbzx({{ Rt = Mem.ub; }}); + 279: lhzx({{ Rt = Mem.uh; }}); + 343: lhax({{ Rt = Mem.sh; }}); + 23: lwzx({{ Rt = Mem; }}); + 341: lwax({{ Rt = Mem.sw; }}); + 20: lwarx({{ Rt = Mem.sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); + 535: lfsx({{ Ft.sf = Mem.sf; }}); + 599: lfdx({{ Ft = Mem.df; }}); + 855: lfiwax({{ Ft.uw = Mem; }}); + } + + format LoadIndexUpdateOp { + 119: lbzux({{ Rt = Mem.ub; }}); + 311: lhzux({{ Rt = Mem.uh; }}); + 375: lhaux({{ Rt = Mem.sh; }}); + 55: lwzux({{ Rt = Mem; }}); + 373: lwaux({{ Rt = Mem.sw; }}); + 567: lfsux({{ Ft.sf = Mem.sf; }}); + 631: lfdux({{ Ft = Mem.df; }}); + } + + format StoreIndexOp { + 215: stbx({{ Mem.ub = Rs.ub; }}); + 407: sthx({{ Mem.uh = Rs.uh; }}); + 151: stwx({{ Mem = Rs; }}); + 150: stwcx({{ + bool store_performed = false; + if (Rsv) { + if (RsvLen == 4) { + if (RsvAddr == EA) { + Mem = Rs; + store_performed = true; + } + } + } + Xer xer = XER; + Cr cr = CR; + cr.cr0 = ((store_performed ? 0x2 : 0x0) | xer.so); + CR = cr; + Rsv = 0; + }}); + 663: stfsx({{ Mem.sf = Fs.sf; }}); + 727: stfdx({{ Mem.df = Fs; }}); + 983: stfiwx({{ Mem = Fs.uw; }}); + } + + format StoreIndexUpdateOp { + 247: stbux({{ Mem.ub = Rs.ub; }}); + 439: sthux({{ Mem.uh = Rs.uh; }}); + 183: stwux({{ Mem = Rs; }}); + 695: stfsux({{ Mem.sf = Fs.sf; }}); + 759: stfdux({{ Mem.df = Fs; }}); + } + + // These instructions all provide data cache hints + format MiscOp { + 278: dcbt({{ }}); + 246: dcbtst({{ }}); + 598: sync({{ }}, [ IsMemBarrier ]); + 854: eieio({{ }}, [ IsMemBarrier ]); + } + } + + format IntImmArithCheckRaOp { + 14: addi({{ Rt = Ra + imm; }}, + {{ Rt = imm }}); + 15: addis({{ Rt = Ra + (imm << 16); }}, + {{ Rt = imm << 16; }}); + } + + format IntImmArithOp { + 12: addic({{ uint32_t src = Ra; Rt = src + imm; }}, + [computeCA]); + 13: addic_({{ uint32_t src = Ra; Rt = src + imm; }}, + [computeCA, computeCR0]); + 8: subfic({{ int32_t src = ~Ra; Rt = src + imm + 1; }}, + [computeCA]); + 7: mulli({{ + int32_t src = Ra.sw; + int64_t prod = src * imm; + Rt = (uint32_t)prod; + }}); + } + + format IntImmLogicOp { + 24: ori({{ Ra = Rs | uimm; }}); + 25: oris({{ Ra = Rs | (uimm << 16); }}); + 26: xori({{ Ra = Rs ^ uimm; }}); + 27: xoris({{ Ra = Rs ^ (uimm << 16); }}); + 28: andi_({{ Ra = Rs & uimm; }}, + true); + 29: andis_({{ Ra = Rs & (uimm << 16); }}, + true); + } + + 16: decode AA { + + // Conditionally branch relative to PC based on CR and CTR. + format BranchPCRelCondCtr { + 0: bc({{ NPC = PC + disp; }}); + } + + // Conditionally branch to fixed address based on CR and CTR. + format BranchNonPCRelCondCtr { + 1: bca({{ NPC = targetAddr; }}); + } + } + + 18: decode AA { + + // Unconditionally branch relative to PC. + format BranchPCRel { + 0: b({{ NPC = PC + disp; }}); + } + + // Unconditionally branch to fixed address. + format BranchNonPCRel { + 1: ba({{ NPC = targetAddr; }}); + } + } + + 19: decode XO_XO { + + // Conditionally branch to address in LR based on CR and CTR. + format BranchLrCondCtr { + 16: bclr({{ NPC = LR & 0xfffffffc; }}); + } + + // Conditionally branch to address in CTR based on CR. + format BranchCtrCond { + 528: bcctr({{ NPC = CTR & 0xfffffffc; }}); + } + + // Condition register manipulation instructions. + format CondLogicOp { + 257: crand({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa & crBb); + }}); + 449: cror({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa | crBb); + }}); + 255: crnand({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, !(crBa & crBb)); + }}); + 193: crxor({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa ^ crBb); + }}); + 33: crnor({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, !(crBa | crBb)); + }}); + 289: creqv({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa == crBb); + }}); + 129: crandc({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa & !crBb); + }}); + 417: crorc({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa | !crBb); + }}); + } + format CondMoveOp { + 0: mcrf({{ + uint32_t crBfa = bits(CR, 31 - bfa*4, 28 - bfa*4); + CR = insertBits(CR, 31 - bf*4, 28 - bf*4, crBfa); + }}); + } + format MiscOp { + 150: isync({{ }}, [ IsSerializeAfter ]); + } + } + + format IntRotateOp { + 21: rlwinm({{ Ra = rotateValue(Rs, sh) & fullMask; }}); + 23: rlwnm({{ Ra = rotateValue(Rs, Rb) & fullMask; }}); + 20: rlwimi({{ Ra = (rotateValue(Rs, sh) & fullMask) | (Ra & ~fullMask); }}); + } + + format LoadDispOp { + 34: lbz({{ Rt = Mem.ub; }}); + 40: lhz({{ Rt = Mem.uh; }}); + 42: lha({{ Rt = Mem.sh; }}); + 32: lwz({{ Rt = Mem; }}); + 58: lwa({{ Rt = Mem.sw; }}, + {{ EA = Ra + (disp & 0xfffffffc); }}, + {{ EA = disp & 0xfffffffc; }}); + 48: lfs({{ Ft.sf = Mem.sf; }}); + 50: lfd({{ Ft = Mem.df; }}); + } + + format LoadDispUpdateOp { + 35: lbzu({{ Rt = Mem.ub; }}); + 41: lhzu({{ Rt = Mem.uh; }}); + 43: lhau({{ Rt = Mem.sh; }}); + 33: lwzu({{ Rt = Mem; }}); + 49: lfsu({{ Ft.sf = Mem.sf; }}); + 51: lfdu({{ Ft = Mem.df; }}); + } + + format StoreDispOp { + 38: stb({{ Mem.ub = Rs.ub; }}); + 44: sth({{ Mem.uh = Rs.uh; }}); + 36: stw({{ Mem = Rs; }}); + 52: stfs({{ Mem.sf = Fs.sf; }}); + 54: stfd({{ Mem.df = Fs; }}); + } + + format StoreDispUpdateOp { + 39: stbu({{ Mem.ub = Rs.ub; }}); + 45: sthu({{ Mem.uh = Rs.uh; }}); + 37: stwu({{ Mem = Rs; }}); + 53: stfsu({{ Mem.sf = Fs.sf; }}); + 55: stfdu({{ Mem.df = Fs; }}); + } + + 17: IntOp::sc({{ xc->syscall(R0); }}, + [ IsSyscall, IsNonSpeculative, IsSerializeAfter ]); + + format FloatArithOp { + 59: decode A_XO { + 21: fadds({{ Ft = Fa + Fb; }}); + 20: fsubs({{ Ft = Fa - Fb; }}); + 25: fmuls({{ Ft = Fa * Fc; }}); + 18: fdivs({{ Ft = Fa / Fb; }}); + 29: fmadds({{ Ft = (Fa * Fc) + Fb; }}); + 28: fmsubs({{ Ft = (Fa * Fc) - Fb; }}); + 31: fnmadds({{ Ft = -((Fa * Fc) + Fb); }}); + 30: fnmsubs({{ Ft = -((Fa * Fc) - Fb); }}); + } + } + + 63: decode A_XO { + format FloatArithOp { + 21: fadd({{ Ft = Fa + Fb; }}); + 20: fsub({{ Ft = Fa - Fb; }}); + 25: fmul({{ Ft = Fa * Fc; }}); + 18: fdiv({{ Ft = Fa / Fb; }}); + 29: fmadd({{ Ft = (Fa * Fc) + Fb; }}); + 28: fmsub({{ Ft = (Fa * Fc) - Fb; }}); + 31: fnmadd({{ Ft = -((Fa * Fc) + Fb); }}); + 30: fnmsub({{ Ft = -((Fa * Fc) - Fb); }}); + } + + default: decode XO_XO { + format FloatConvertOp { + 12: frsp({{ Ft.sf = Fb; }}); + 15: fctiwz({{ Ft.sw = (int32_t)trunc(Fb); }}); + } + + format FloatOp { + 0: fcmpu({{ + uint32_t c = makeCRField(Fa, Fb); + Fpscr fpscr = FPSCR; + fpscr.fprf.fpcc = c; + FPSCR = fpscr; + CR = insertCRField(CR, BF, c); + }}); + } + + format FloatRCCheckOp { + 72: fmr({{ Ft = Fb; }}); + 264: fabs({{ + Ft.uq = Fb.uq; + Ft.uq = insertBits(Ft.uq, 63, 0); }}); + 136: fnabs({{ + Ft.uq = Fb.uq; + Ft.uq = insertBits(Ft.uq, 63, 1); }}); + 40: fneg({{ Ft = -Fb; }}); + 8: fcpsgn({{ + Ft.uq = Fb.uq; + Ft.uq = insertBits(Ft.uq, 63, Fa.uq<63:63>); + }}); + 583: mffs({{ Ft.uq = FPSCR; }}); + 134: mtfsfi({{ + FPSCR = insertCRField(FPSCR, BF + (8 * (1 - W)), U_FIELD); + }}); + 711: mtfsf({{ + if (L == 1) { FPSCR = Fb.uq; } + else { + for (int i = 0; i < 8; ++i) { + if (bits(FLM, i) == 1) { + int k = 4 * (i + (8 * (1 - W))); + FPSCR = insertBits(FPSCR, k, k + 3, + bits(Fb.uq, k, k + 3)); + } + } + } + }}); + 70: mtfsb0({{ FPSCR = insertBits(FPSCR, 31 - BT, 0); }}); + 38: mtfsb1({{ FPSCR = insertBits(FPSCR, 31 - BT, 1); }}); + } + } + } +} diff --git a/src/arch/power/isa/formats/basic.isa b/src/arch/power/isa/formats/basic.isa new file mode 100644 index 0000000000..adb5e7ef86 --- /dev/null +++ b/src/arch/power/isa/formats/basic.isa @@ -0,0 +1,103 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +// Declarations for execute() methods. +def template BasicExecDeclare {{ + Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + +// Basic instruction class declaration template. +def template BasicDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + /// Constructor. + %(class_name)s(ExtMachInst machInst); + %(BasicExecDeclare)s + }; +}}; + +// Basic instruction class constructor template. +def template BasicConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + + +// Basic instruction class execute method template. +def template BasicExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == NoFault) + { + %(op_wb)s; + } + + return fault; + } +}}; + +// Basic decode template. +def template BasicDecode {{ + return new %(class_name)s(machInst); +}}; + +// Basic decode template, passing mnemonic in as string arg to constructor. +def template BasicDecodeWithMnemonic {{ + return new %(class_name)s("%(mnemonic)s", machInst); +}}; + +// Definitions of execute methods that panic. +def template BasicExecPanic {{ +Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const +{ + panic("Execute method called when it shouldn't!"); +} +}}; + +// The most basic instruction format... +def format BasicOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'PowerStaticInst', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/power/isa/formats/branch.isa b/src/arch/power/isa/formats/branch.isa new file mode 100644 index 0000000000..d51ed5c259 --- /dev/null +++ b/src/arch/power/isa/formats/branch.isa @@ -0,0 +1,222 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Control transfer instructions +// +// From the Power ISA Book I v2.06, page 33, the following rules should +// be obeyed by programmers: +// +// - Use branch instructions where LK == 1 only as subroutine calls. +// - Pair each subroutine call with a bclr instruction with BH == 00 +// that returns from the subroutine. +// - Do not use bclrl as a subroutine call. +// +// Therefore, I've flagged all versions that update the link register (LR) +// as calls, except bclrl (BranchLrCtrCond format) which is flagged as +// a return. + + +let {{ + +# Simple code to update link register (LR). +updateLrCode = 'LR = PC + 4;' + +}}; + +// Instructions that unconditionally branch relative to the current PC. +def format BranchPCRel(br_code, inst_flags = []) {{ + inst_flags += ('IsUncondControl', 'IsDirectControl') + basic_code = br_code + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchPCRel', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchPCRel', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that unconditionally branch to a specific address. +def format BranchNonPCRel(br_code, inst_flags = []) {{ + inst_flags += ('IsUncondControl', 'IsDirectControl') + basic_code = br_code + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchNonPCRel', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRel', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +let {{ + +# Check the condition register (CR) allows the branch to be taken. +def GetCondCode(br_code): + cond_code = 'if(condOk(CR)) {\n' + cond_code += ' ' + br_code + '\n' + cond_code += '} else {\n' + cond_code += ' NPC = NPC;\n' + cond_code += '}\n' + return cond_code + +# Check the condition register (CR) and count register (CTR) allow the +# branch to be taken. Also, in certain situations, decrement the count +# register too. This takes place in ctrOk within BranchCond classes. +def GetCtrCondCode(br_code): + cond_code = 'uint32_t ctr = CTR;\n' + cond_code += 'bool ctr_ok = ctrOk(ctr);\n' + cond_code += 'bool cond_ok = condOk(CR);\n' + cond_code += 'if(ctr_ok && cond_ok) {\n' + cond_code += ' ' + br_code + '\n' + cond_code += '} else {\n' + cond_code += ' NPC = NPC;\n' + cond_code += '}\n' + cond_code += 'CTR = ctr;\n' + return cond_code + +}}; + +// Instructions that conditionally branch relative to the current PC based on +// the condition register (CR) and count register (CTR). +def format BranchPCRelCondCtr(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsDirectControl') + basic_code = GetCtrCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchPCRelCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchPCRelCond', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that conditionally branch to a specific address based on the +// condition register (CR) and count register (CTR). +def format BranchNonPCRelCondCtr(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsDirectControl') + basic_code = GetCtrCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchNonPCRelCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRelCond', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that conditionally branch to the address in the link register +// (LR) based on the condition register (CR) and count register (CTR). +def format BranchLrCondCtr(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsIndirectControl', 'IsReturn') + basic_code = GetCtrCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code, + inst_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that conditionally branch to the address in the count register +// (CTR) based on the condition register (CR). +def format BranchCtrCond(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsIndirectControl') + basic_code = GetCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; diff --git a/src/arch/power/isa/formats/condition.isa b/src/arch/power/isa/formats/condition.isa new file mode 100644 index 0000000000..12ee7ae7d3 --- /dev/null +++ b/src/arch/power/isa/formats/condition.isa @@ -0,0 +1,47 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +// Logical instructions that manipulate the condition register +def format CondLogicOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'CondLogicOp', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +// Instructions that condition register fields +def format CondMoveOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'CondMoveOp', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/power/isa/formats/formats.isa b/src/arch/power/isa/formats/formats.isa new file mode 100644 index 0000000000..ec25751960 --- /dev/null +++ b/src/arch/power/isa/formats/formats.isa @@ -0,0 +1,60 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//Templates from this format are used later +//Include the basic format +##include "basic.isa" + +//Include integer instructions +##include "integer.isa" + +//Include condition register instructions +##include "condition.isa" + +//Include utility functions +##include "util.isa" + +//Include the float formats +##include "fp.isa" + +//Include the mem format +##include "mem.isa" + +//Include the branch format +##include "branch.isa" + +//Include the misc format +##include "misc.isa" + +//Include the unimplemented format +##include "unimp.isa" + +//Include the unknown format +##include "unknown.isa" diff --git a/src/arch/power/isa/formats/fp.isa b/src/arch/power/isa/formats/fp.isa new file mode 100644 index 0000000000..db917476ec --- /dev/null +++ b/src/arch/power/isa/formats/fp.isa @@ -0,0 +1,132 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Floating Point operate instructions +// + + +let {{ + + readFPSCRCode = 'Fpscr fpscr = FPSCR;' + + computeCR1Code = ''' + Cr cr = CR; + cr.cr1 = (fpscr.fx << 3) | (fpscr.fex << 2) | + (fpscr.vx << 1) | fpscr.ox; + CR = cr; + ''' + +}}; + +// Primary format for floating point operate instructions: +def format FloatOp(code, inst_flags = []) {{ + iop = InstObjParams(name, Name, 'FloatOp', + {"code": code}, + inst_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +// Floating point operations that compute the CR1 code if RC is set. No other +// special registers are touched using these operations. +def format FloatRCCheckOp(code, inst_flags = []) {{ + + # Code when Rc is set + code_rc1 = code + readFPSCRCode + computeCR1Code + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'FloatOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + +// Floating point elementary arithmetic operations. Besides having two +// versions of each instruction for when Rc is set or not, we also have +// to alter lots of special registers depending on the result of the +// operation. The result is always in Ft.sf. +def format FloatArithOp(code, inst_flags = []) {{ + + # Code when Rc is set + code_rc1 = code + readFPSCRCode + computeCR1Code + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'FloatOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + +// Floating point rounding and conversion operations. Besides having two +// versions of each instruction for when Rc is set or not, we also have +// to alter lots of special registers depending on the result of the +// operation. The result is always in Ft.sf. +def format FloatConvertOp(code, inst_flags = []) {{ + + # Code when Rc is set + code_rc1 = code + readFPSCRCode + computeCR1Code + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'FloatOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa new file mode 100644 index 0000000000..0766826ec8 --- /dev/null +++ b/src/arch/power/isa/formats/integer.isa @@ -0,0 +1,369 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Integer ALU instructions +// + + +// Instruction class constructor template when Rc is set. +def template IntRcConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + rcSet = true; + } +}}; + + +// Instruction class constructor template when OE is set. +def template IntOeConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + oeSet = true; + } +}}; + + +// Instruction class constructor template when both Rc and OE are set. +def template IntRcOeConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + rcSet = true; + oeSet = true; + } +}}; + + +let {{ + +readXERCode = 'Xer xer = XER;' + +setXERCode = 'XER = xer;' + +computeCR0Code = ''' + Cr cr = CR; + cr.cr0 = makeCRField((int32_t)%(result)s, (int32_t)0, xer.so); + CR = cr; +''' + +computeCACode = ''' + if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ca = 1; + } else { + xer.ca = 0; + } +''' + +computeOVCode = ''' + if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ov = 1; + xer.so = 1; + } else { + xer.ov = 0; + } +''' + +computeDivOVCode = ''' + if (divSetOV) { + xer.ov = 1; + xer.so = 1; + } else { + if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ov = 1; + xer.so = 1; + } else { + xer.ov = 0; + } + } +''' + +}}; + + +// A basic integer instruction. +def format IntOp(code, inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions with immediate (signed or unsigned). +def format IntImmOp(code, inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions with immediate that perform arithmetic. +// These instructions all write to Rt and use an altered form of the +// value in source register Ra, hence the use of src to hold the actual +// value. The control flags include the use of code to compute the +// carry bit or the CR0 code. +def format IntImmArithOp(code, ctrl_flags = [], inst_flags = []) {{ + + # Set up the dictionary and deal with control flags + dict = {'result':'Rt', 'inputa':'src', 'inputb':'imm'} + if ctrl_flags: + code += readXERCode + for val in ctrl_flags: + if val == 'computeCA': + code += computeCACode % dict + setXERCode + elif val == 'computeCR0': + code += computeCR0Code % dict + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions with immediate that perform arithmetic but use +// the value 0 when Ra == 0. We generate two versions of each instruction +// corresponding to these two different scenarios. The correct version is +// determined at decode (see the CheckRaDecode template). +def format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{ + + # First the version where Ra is non-zero + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, + CheckRaDecode, BasicConstructor) + + # Now another version where Ra == 0 + (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ + GenAluOp(name, Name + 'RaZero', 'IntImmOp', code_ra0, inst_flags, + CheckRaDecode, BasicConstructor) + + # Finally, add to the other outputs + header_output += header_output_ra0 + decoder_output += decoder_output_ra0 + exec_output += exec_output_ra0 +}}; + + +// Integer instructions with immediate that perform logic operations. +// All instructions write to Ra and use Rs as a source register. Some +// also compute the CR0 code too. +def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{ + + # Set up the dictionary and deal with computing CR0 + dict = {'result':'Ra'} + if computeCR0: + code += readXERCode + computeCR0Code % dict + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions that perform logic operations. The result is +// always written into Ra. All instructions have 2 versions depending on +// whether the Rc bit is set to compute the CR0 code. This is determined +// at decode as before. +def format IntLogicOp(code, inst_flags = []) {{ + dict = {'result':'Ra'} + + # Code when Rc is set + code_rc1 = code + readXERCode + computeCR0Code % dict + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + + +// Integer instructions with a shift amount. As above, except inheriting +// from the IntShiftOp class. +def format IntShiftOp(code, inst_flags = []) {{ + dict = {'result':'Ra'} + + # Code when Rc is set + code_rc1 = code + readXERCode + computeCR0Code % dict + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntShiftOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + + +// Instructions in this format are all reduced to the form Rt = src1 + src2, +// therefore we just give src1 and src2 definitions. In working out the +// template we first put in the definitions of the variables and then +// the code for the addition. We also deal with computing the carry flag +// if required. +// +// We generate 4 versions of each instruction. This correspond to the +// different combinations of having the OE bit set or unset (which controls +// whether the overflow flag is computed) and the Rc bit set or unset too +// (which controls whether the CR0 code is computed). +def format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0, + inst_flags = []) {{ + + # The result is always in Rt, but the source values vary + dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'} + + # Add code to set up variables and do the sum + code = 'uint32_t src1 = ' + src1 + ';\n' + code += 'uint32_t src2 = ' + src2 + ';\n' + code += 'uint32_t ca = ' + ca + ';\n' + code += 'Rt = src1 + src2 + ca;\n' + + # Add code for calculating the carry, if needed + if computeCA: + code += computeCACode % dict + setXERCode + + # Setup the 4 code versions and add code to access XER if necessary + code_rc1 = readXERCode + code + code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode + code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode + if (computeCA or ca == 'xer.ca'): + code = readXERCode + code + code_rc1 += computeCR0Code % dict + code_rc1_oe1 += computeCR0Code % dict + + # Generate the classes + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, + CheckRcOeDecode, BasicConstructor) + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, + CheckRcOeDecode, IntRcConstructor) + (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \ + GenAluOp(name, Name + 'OeSet', 'IntOp', code_oe1, inst_flags, + CheckRcOeDecode, IntOeConstructor) + (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \ + GenAluOp(name, Name + 'RcSetOeSet', 'IntOp', code_rc1_oe1, + inst_flags, CheckRcOeDecode, IntRcOeConstructor) + + # Finally, add to the other outputs + header_output += \ + header_output_rc1 + header_output_oe1 + header_output_rc1_oe1 + decoder_output += \ + decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1 + exec_output += \ + exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1 + +}}; + + +// Instructions that use source registers Ra and Rb, with the result +// placed into Rt. Basically multiply and divide instructions. The +// carry bit is never set, but overflow can be calculated. Division +// explicitly sets the overflow bit in certain situations and this is +// dealt with using the 'divSetOV' boolean in decoder.isa. We generate +// two versions of each instruction to deal with the Rc bit. +def format IntArithOp(code, computeOV = 0, inst_flags = []) {{ + + # The result is always in Rt, but the source values vary + dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'} + + # Deal with setting the overflow flag + if computeOV: + code = 'bool divSetOV = false;\n' + code + code += computeDivOVCode % dict + setXERCode + + # Setup the 2 code versions and add code to access XER if necessary + code_rc1 = readXERCode + code + computeCR0Code % dict + if computeOV: + code = readXERCode + code + + # Generate the classes + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + + +// A special format for rotate instructions which use certain fields +// from the instruction's binary encoding. We need two versions for each +// instruction to deal with the Rc bit. +def format IntRotateOp(code, inst_flags = []) {{ + + # The result is always in Ra + dict = {'result':'Ra'} + + # Setup the code for when Rc is set + code_rc1 = readXERCode + code + computeCR0Code % dict + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntRotateOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa new file mode 100644 index 0000000000..1be49c2f7f --- /dev/null +++ b/src/arch/power/isa/formats/mem.isa @@ -0,0 +1,351 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Memory-format instructions +// + +def template LoadStoreDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + + /// Constructor. + %(class_name)s(ExtMachInst machInst); + + %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s + }; +}}; + + +def template InitiateAccDeclare {{ + Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template CompleteAccDeclare {{ + Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template LoadStoreConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + + +def template LoadExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template LoadInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_src_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); + xc->setEA(EA); + } + + return fault; + } +}}; + + +def template LoadCompleteAcc {{ + Fault %(class_name)s::completeAcc(PacketPtr pkt, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + uint%(mem_acc_size)d_t val; + + %(op_decl)s; + %(op_rd)s; + + EA = xc->getEA(); + + val = pkt->get(); + *((uint%(mem_acc_size)d_t*)&Mem) = val; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, NULL); + if (traceData) { traceData->setData(Mem); } + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, NULL); + if (traceData) { traceData->setData(Mem); } + } + + // Need to write back any potential address register update + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreCompleteAcc {{ + Fault %(class_name)s::completeAcc(PacketPtr pkt, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(op_dest_decl)s; + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +// The generic memory operation generator. This is called when two versions +// of an instruction are needed - when Ra == 0 and otherwise. This is so +// that instructions can use the value 0 when Ra == 0 but avoid having a +// dependence on Ra. +let {{ + +def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, + load_or_store, mem_flags = [], inst_flags = []): + + # First the version where Ra is non-zero + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = base, + decode_template = CheckRaDecode, + exec_template_base = load_or_store) + + # Now another version where Ra == 0 + (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ + LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, + mem_flags, inst_flags, + base_class = base, + exec_template_base = load_or_store) + + # Finally, add to the other outputs + header_output += header_output_ra0 + decoder_output += decoder_output_ra0 + exec_output += exec_output_ra0 + return (header_output, decoder_output, decode_block, exec_output) + +}}; + + +def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + ea_code_ra0 = {{ EA = Rb; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemOp', 'Load', mem_flags, inst_flags) +}}; + + +def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + ea_code_ra0 = {{ EA = Rb; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemOp', 'Store', mem_flags, inst_flags) +}}; + + +def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemOp', + exec_template_base = 'Load') +}}; + + +def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemOp', + exec_template_base = 'Store') +}}; + + +def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + ea_code_ra0 = {{ EA = disp; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemDispOp', 'Load', mem_flags, inst_flags) +}}; + + +def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + ea_code_ra0 = {{ EA = disp; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemDispOp', 'Store', mem_flags, inst_flags) +}}; + + +def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemDispOp', + exec_template_base = 'Load') +}}; + + +def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemDispOp', + exec_template_base = 'Store') +}}; diff --git a/src/arch/power/isa/formats/misc.isa b/src/arch/power/isa/formats/misc.isa new file mode 100644 index 0000000000..93536aa182 --- /dev/null +++ b/src/arch/power/isa/formats/misc.isa @@ -0,0 +1,61 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Misc instructions +// + +def template MiscOpExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + %(op_decl)s; + %(op_rd)s; + + %(code)s; + if (fault == NoFault) + { + %(op_wb)s; + } + + return fault; + } +}}; + +def format MiscOp(code, opt_flags = []) {{ + iop = InstObjParams(name, Name, 'IntOp', + {"code": code}, + opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = MiscOpExecute.subst(iop) +}}; diff --git a/src/arch/power/isa/formats/unimp.isa b/src/arch/power/isa/formats/unimp.isa new file mode 100644 index 0000000000..60a7c469d8 --- /dev/null +++ b/src/arch/power/isa/formats/unimp.isa @@ -0,0 +1,146 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2007-2008 The Florida State University +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Stephen Hines +// Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Unimplemented instructions +// + +output header {{ + /** + * Static instruction class for unimplemented instructions that + * cause simulator termination. Note that these are recognized + * (legal) instructions that the simulator does not support; the + * 'Unknown' class is used for unrecognized/illegal instructions. + * This is a leaf class. + */ + class FailUnimplemented : public PowerStaticInst + { + public: + /// Constructor + FailUnimplemented(const char *_mnemonic, MachInst _machInst) + : PowerStaticInst(_mnemonic, _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for unimplemented instructions that cause a warning + * to be printed (but do not terminate simulation). This + * implementation is a little screwy in that it will print a + * warning for each instance of a particular unimplemented machine + * instruction, not just for each unimplemented opcode. Should + * probably make the 'warned' flag a static member of the derived + * class. + */ + class WarnUnimplemented : public PowerStaticInst + { + private: + /// Have we warned on this instruction yet? + mutable bool warned; + + public: + /// Constructor + WarnUnimplemented(const char *_mnemonic, MachInst _machInst) + : PowerStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + FailUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } + + std::string + WarnUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } +}}; + +output exec {{ + Fault + FailUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE, + inst2string(machInst)); + return new UnimplementedOpcodeFault; + } + + Fault + WarnUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (!warned) { + warn("\tinstruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return NoFault; + } +}}; + + +def format FailUnimpl() {{ + iop = InstObjParams(name, 'FailUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +def format WarnUnimpl() {{ + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + diff --git a/src/arch/power/isa/formats/unknown.isa b/src/arch/power/isa/formats/unknown.isa new file mode 100644 index 0000000000..06e6ece262 --- /dev/null +++ b/src/arch/power/isa/formats/unknown.isa @@ -0,0 +1,87 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2007-2008 The Florida State University +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Stephen Hines +// Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Unknown instructions +// + +output header {{ + /** + * Static instruction class for unknown (illegal) instructions. + * These cause simulator termination if they are executed in a + * non-speculative mode. This is a leaf class. + */ + class Unknown : public PowerStaticInst + { + public: + /// Constructor + Unknown(ExtMachInst _machInst) + : PowerStaticInst("unknown", _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)", + "unknown", machInst, OPCODE, inst2string(machInst)); + } +}}; + +output exec {{ + Fault + Unknown::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unknown instruction at %#x" + "(inst 0x%08x, opcode 0x%x, binary: %s)", + xc->readPC(), machInst, OPCODE, inst2string(machInst)); + return new UnimplementedOpcodeFault; + } +}}; + +def format Unknown() {{ + decode_block = 'return new Unknown(machInst);\n' +}}; + diff --git a/src/arch/power/isa/formats/util.isa b/src/arch/power/isa/formats/util.isa new file mode 100644 index 0000000000..ab1e530b2b --- /dev/null +++ b/src/arch/power/isa/formats/util.isa @@ -0,0 +1,174 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2005 The Regents of The University of Michigan +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Steve Reinhardt +// Korey Sewell +// Timothy M. Jones + +// Some instructions ignore the contents of Ra if Ra == 0, +// so check for this. +def template CheckRaDecode {{ + { + if (RA == 0) { + return new %(class_name)sRaZero(machInst); + } else { + return new %(class_name)s(machInst); + } + } +}}; + + +// Some instructions have extra behaviour if Rc is set. +def template CheckRcDecode {{ + { + if (RC31 == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sRcSet(machInst); + } + } +}}; + + +// Some instructions have extra behaviour if Rc and OE are set. +def template CheckRcOeDecode {{ + { + if (RC31 == 0) { + if (OE == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sOeSet(machInst); + } + } else { + if (OE == 0) { + return new %(class_name)sRcSet(machInst); + } else { + return new %(class_name)sRcSetOeSet(machInst); + } + } + } +}}; + +// Branch instructions always have two versions, one which sets the link +// register (LR). +def template CheckLkDecode {{ + { + if (LK == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sUpdateLr(machInst); + } + } +}}; + + +let {{ + +def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemOp', + decode_template = BasicDecode, exec_template_base = ''): + # Make sure flags are in lists (convert to lists if not). + mem_flags = makeList(mem_flags) + inst_flags = makeList(inst_flags) + + # add hook to get effective addresses into execution trace output. + ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' + + # Generate InstObjParams for the memory access. + iop = InstObjParams(name, Name, base_class, + {'ea_code': ea_code, + 'memacc_code': memacc_code}, + inst_flags) + + if mem_flags: + s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' + iop.constructor += s + + fullExecTemplate = eval(exec_template_base + 'Execute') + initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') + completeAccTemplate = eval(exec_template_base + 'CompleteAcc') + + # (header_output, decoder_output, decode_block, exec_output) + return (LoadStoreDeclare.subst(iop), + LoadStoreConstructor.subst(iop), + decode_template.subst(iop), + fullExecTemplate.subst(iop) + + initiateAccTemplate.subst(iop) + + completeAccTemplate.subst(iop)) + + +# The generic ALU instruction generator. Integer and fp formats calls this +# to generate the different output sections. +def GenAluOp(name, Name, base_class, code, inst_flags, decode_template, + constructor_template): + iop = InstObjParams(name, Name, base_class, + {"code": code}, + inst_flags) + header_output = BasicDeclare.subst(iop) + exec_output = BasicExecute.subst(iop) + + # We use constructors dependent on the Rc and OE bits being set + decoder_output = constructor_template.subst(iop) + + # The decode block defines which version to use + decode_block = decode_template.subst(iop) + return (header_output, decoder_output, decode_block, exec_output) + +}}; + + +output header {{ + std::string + inst2string(MachInst machInst); +}}; + +output decoder {{ + + std::string + inst2string(MachInst machInst) + { + std::string str = ""; + uint32_t mask = 0x80000000; + + for(int i=0; i < 32; i++) { + if ((machInst & mask) == 0) { + str += "0"; + } else { + str += "1"; + } + + mask = mask >> 1; + } + + return str; + } + +}}; + + diff --git a/src/arch/power/isa/includes.isa b/src/arch/power/isa/includes.isa new file mode 100644 index 0000000000..47e8c1411c --- /dev/null +++ b/src/arch/power/isa/includes.isa @@ -0,0 +1,92 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Output include file directives. +// + +output header {{ +#include +#include +#include + +#include "arch/power/insts/branch.hh" +#include "arch/power/insts/mem.hh" +#include "arch/power/insts/integer.hh" +#include "arch/power/insts/floating.hh" +#include "arch/power/insts/condition.hh" +#include "arch/power/insts/misc.hh" +#include "arch/power/insts/static_inst.hh" +#include "arch/power/isa_traits.hh" +#include "cpu/static_inst.hh" +#include "mem/packet.hh" + +using namespace PowerISA; +}}; + +output decoder {{ +#include +#if defined(linux) +#include +#endif + +#include "arch/power/faults.hh" +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" +#include "base/cprintf.hh" +#include "base/loader/symtab.hh" +#include "cpu/thread_context.hh" + +using namespace PowerISA; +using std::isnan; +}}; + +output exec {{ +#include "arch/power/faults.hh" +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" + +#include +#if defined(linux) +#include +#endif + +#include "base/condcodes.hh" +#include "cpu/base.hh" +#include "cpu/exetrace.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "sim/sim_exit.hh" + +using namespace PowerISA; +using std::isnan; +}}; + diff --git a/src/arch/power/isa/main.isa b/src/arch/power/isa/main.isa new file mode 100644 index 0000000000..cce7e39ee0 --- /dev/null +++ b/src/arch/power/isa/main.isa @@ -0,0 +1,57 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Power ISA description file. +// +//////////////////////////////////////////////////////////////////// + +//Include the C++ include directives +##include "includes.isa" + +//////////////////////////////////////////////////////////////////// +// +// Namespace statement. Everything below this line will be in the +// PowerISAInst namespace. +// +namespace PowerISA; + +//Include the bitfield definitions +##include "bitfields.isa" + +//Include the operand_types and operand definitions +##include "operands.isa" + +//Include the definitions for the instruction formats +##include "formats/formats.isa" + +//Include the decoder definition +##include "decoder.isa" diff --git a/src/arch/power/isa/operands.isa b/src/arch/power/isa/operands.isa new file mode 100644 index 0000000000..fc6c326859 --- /dev/null +++ b/src/arch/power/isa/operands.isa @@ -0,0 +1,81 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +def operand_types {{ + 'sb' : ('signed int', 8), + 'ub' : ('unsigned int', 8), + 'sh' : ('signed int', 16), + 'uh' : ('unsigned int', 16), + 'sw' : ('signed int', 32), + 'uw' : ('unsigned int', 32), + 'sq' : ('signed int', 64), + 'uq' : ('unsigned int', 64), + 'sf' : ('float', 32), + 'df' : ('float', 64) +}}; + +def operands {{ + # General Purpose Integer Reg Operands + 'Ra': ('IntReg', 'uw', 'RA', 'IsInteger', 1), + 'Rb': ('IntReg', 'uw', 'RB', 'IsInteger', 2), + 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3), + 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 4), + + # General Purpose Floating Point Reg Operands + 'Fa': ('FloatReg', 'df', 'FRA', 'IsFloating', 1), + 'Fb': ('FloatReg', 'df', 'FRB', 'IsFloating', 2), + 'Fc': ('FloatReg', 'df', 'FRC', 'IsFloating', 3), + 'Fs': ('FloatReg', 'df', 'FRS', 'IsFloating', 4), + 'Ft': ('FloatReg', 'df', 'FRT', 'IsFloating', 5), + + # Memory Operand + 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 8), + + # Program counter and next + 'PC': ('PC', 'uw', None, (None, None, 'IsControl'), 9), + 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 9), + + # Control registers + 'CR': ('IntReg', 'uw', 'INTREG_CR', 'IsInteger', 9), + 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9), + 'CTR': ('IntReg', 'uw', 'INTREG_CTR', 'IsInteger', 9), + 'XER': ('IntReg', 'uw', 'INTREG_XER', 'IsInteger', 9), + + # Setting as IntReg so things are stored as an integer, not double + 'FPSCR': ('IntReg', 'uw', 'INTREG_FPSCR', 'IsFloating', 9), + + # Registers for linked loads and stores + 'Rsv': ('IntReg', 'uw', 'INTREG_RSV', 'IsInteger', 9), + 'RsvLen': ('IntReg', 'uw', 'INTREG_RSV_LEN', 'IsInteger', 9), + 'RsvAddr': ('IntReg', 'uw', 'INTREG_RSV_ADDR', 'IsInteger', 9), + + # Hack for non-full-system syscall emulation + 'R0': ('IntReg', 'uw', '0', None, 1), +}}; diff --git a/src/arch/power/isa_traits.hh b/src/arch/power/isa_traits.hh new file mode 100644 index 0000000000..886c2cb0bc --- /dev/null +++ b/src/arch/power/isa_traits.hh @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + * Gabe Black + * Stephen Hines + */ + +#ifndef __ARCH_POWER_ISA_TRAITS_HH__ +#define __ARCH_POWER_ISA_TRAITS_HH__ + +#include "arch/power/types.hh" +#include "base/types.hh" + +namespace BigEndianGuest {}; + +class StaticInstPtr; + +namespace PowerISA +{ + +using namespace BigEndianGuest; + +StaticInstPtr decodeInst(ExtMachInst); + +// POWER DOES NOT have a delay slot +#define ISA_HAS_DELAY_SLOT 0 + +const Addr PageShift = 12; +const Addr PageBytes = ULL(1) << PageShift; +const Addr Page_Mask = ~(PageBytes - 1); +const Addr PageOffset = PageBytes - 1; + +const Addr PteShift = 3; +const Addr NPtePageShift = PageShift - PteShift; +const Addr NPtePage = ULL(1) << NPtePageShift; +const Addr PteMask = NPtePage - 1; + +const int LogVMPageSize = 12; // 4K bytes +const int VMPageSize = (1 << LogVMPageSize); + +const int MachineBytes = 4; + +// This is ori 0, 0, 0 +const ExtMachInst NoopMachInst = 0x60000000; + +} // PowerISA namespace + +#endif // __ARCH_POWER_ISA_TRAITS_HH__ diff --git a/src/arch/power/linux/linux.cc b/src/arch/power/linux/linux.cc new file mode 100644 index 0000000000..113f3e48e2 --- /dev/null +++ b/src/arch/power/linux/linux.cc @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/linux/linux.hh" + +#include + +// open(2) flags translation table +OpenFlagTransTable PowerLinux::openFlagTable[] = { +#ifdef _MSC_VER + { PowerLinux::TGT_O_RDONLY, _O_RDONLY }, + { PowerLinux::TGT_O_WRONLY, _O_WRONLY }, + { PowerLinux::TGT_O_RDWR, _O_RDWR }, + { PowerLinux::TGT_O_APPEND, _O_APPEND }, + { PowerLinux::TGT_O_CREAT, _O_CREAT }, + { PowerLinux::TGT_O_TRUNC, _O_TRUNC }, + { PowerLinux::TGT_O_EXCL, _O_EXCL }, +#ifdef _O_NONBLOCK + { PowerLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, +#endif +#ifdef _O_NOCTTY + { PowerLinux::TGT_O_NOCTTY, _O_NOCTTY }, +#endif +#ifdef _O_SYNC + { PowerLinux::TGT_O_SYNC, _O_SYNC }, +#endif +#ifdef _O_LARGEFILE + { PowerLinux::TGT_O_LARGEFILE, _O_LARGEFILE }, +#endif +#else /* !_MSC_VER */ + { PowerLinux::TGT_O_RDONLY, O_RDONLY }, + { PowerLinux::TGT_O_WRONLY, O_WRONLY }, + { PowerLinux::TGT_O_RDWR, O_RDWR }, + { PowerLinux::TGT_O_APPEND, O_APPEND }, + { PowerLinux::TGT_O_CREAT, O_CREAT }, + { PowerLinux::TGT_O_TRUNC, O_TRUNC }, + { PowerLinux::TGT_O_EXCL, O_EXCL }, + { PowerLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { PowerLinux::TGT_O_NOCTTY, O_NOCTTY }, +#ifdef O_SYNC + { PowerLinux::TGT_O_SYNC, O_SYNC }, +#endif +#ifdef O_LARGEFILE + { PowerLinux::TGT_O_LARGEFILE, O_LARGEFILE }, +#endif +#endif /* _MSC_VER */ +}; + +const int PowerLinux::NUM_OPEN_FLAGS = + (sizeof(PowerLinux::openFlagTable)/sizeof(PowerLinux::openFlagTable[0])); + diff --git a/src/arch/power/linux/linux.hh b/src/arch/power/linux/linux.hh new file mode 100644 index 0000000000..c681c8baf6 --- /dev/null +++ b/src/arch/power/linux/linux.hh @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_LINUX_LINUX_HH__ +#define __ARCH_POWER_LINUX_LINUX_HH__ + +#include "kern/linux/linux.hh" + +/* + * This works for a 2.6.15 kernel. + */ + +class PowerLinux : public Linux +{ + public: + + typedef int32_t time_t; + + typedef struct { + uint64_t st_dev; + uint32_t __pad1; + uint32_t st_ino; + uint32_t st_mode; + uint32_t st_nlink; + uint32_t st_uid; + uint32_t st_gid; + uint64_t st_rdev; + uint32_t __pad2; + uint32_t st_size; + uint32_t st_blksize; + uint32_t st_blocks; + uint32_t st_atimeX; + uint32_t st_atime_nsec; + uint32_t st_mtimeX; + uint32_t st_mtime_nsec; + uint32_t st_ctimeX; + uint32_t st_ctime_nsec; + uint32_t __unused4; + uint32_t __unused5; + } tgt_stat; + + typedef struct { + uint64_t st_dev; + uint64_t st_ino; + uint32_t st_mode; + uint32_t st_nlink; + uint32_t st_uid; + uint32_t st_gid; + uint64_t st_rdev; + uint64_t __pad2; + uint64_t st_size; + uint32_t st_blksize; + uint32_t __blksize_pad; + uint64_t st_blocks; + uint32_t st_atimeX; + uint32_t st_atime_nsec; + uint32_t st_mtimeX; + uint32_t st_mtime_nsec; + uint32_t st_ctimeX; + uint32_t st_ctime_nsec; + uint32_t __unused4; + uint32_t __unused5; + } tgt_stat64; + + /// For times(). + struct tms { + int32_t tms_utime; //!< user time + int32_t tms_stime; //!< system time + int32_t tms_cutime; //!< user time of children + int32_t tms_cstime; //!< system time of children + }; + + /// This table maps the target open() flags to the corresponding + /// host open() flags. + static OpenFlagTransTable openFlagTable[]; + + /// Number of entries in openFlagTable[]. + static const int NUM_OPEN_FLAGS; + + //@{ + /// open(2) flag values. + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_CREAT = 00000100; //!< O_CREAT + static const int TGT_O_EXCL = 00000200; //!< O_EXCL + static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY + static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC + static const int TGT_O_APPEND = 00002000; //!< O_APPEND + static const int TGT_O_NONBLOCK = 00004000; //!< O_NONBLOCK + static const int TGT_O_SYNC = 00010000; //!< O_SYNC + static const int TGT_FASYNC = 00020000; //!< FASYNC + static const int TGT_O_DIRECTORY = 00040000; //!< O_DIRECTORY + static const int TGT_O_NOFOLLOW = 00100000; //!< O_NOFOLLOW + static const int TGT_O_LARGEFILE = 00200000; //!< O_LARGEFILE + static const int TGT_O_DIRECT = 00400000; //!< O_DIRECT + static const int TGT_O_NOATIME = 01000000; //!< O_NOATIME + //@} + + /// For mmap(). + static const unsigned TGT_MAP_ANONYMOUS = 0x800; + + //@{ + /// ioctl() command codes. + /// These are for the 2.6.15 kernel. Some have changed for + /// later versions. + static const unsigned TIOCGETP_ = 0x40067408; + static const unsigned TIOCSETP_ = 0x80067409; + static const unsigned TIOCSETN_ = 0x8006740a; + static const unsigned TIOCSETC_ = 0x80067411; + static const unsigned TIOCGETC_ = 0x40067412; + static const unsigned FIONREAD_ = 0x4004667f; + static const unsigned TIOCISATTY_ = 0x2000745e; + static const unsigned TIOCGETS_ = 0x402c7413; + static const unsigned TIOCGETA_ = 0x40147417; + static const unsigned TCSETAW_ = 0x80147419; + //@} +}; + +#endif // __ARCH_POWER_LINUX_LINUX_HH__ diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc new file mode 100644 index 0000000000..b03ccfc8c1 --- /dev/null +++ b/src/arch/power/linux/process.cc @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Korey Sewell + * Stephen Hines + * Timothy M. Jones + */ + +#include "arch/power/linux/linux.hh" +#include "arch/power/linux/process.hh" +#include "arch/power/isa_traits.hh" + +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "kern/linux/linux.hh" + +#include "sim/process.hh" +#include "sim/syscall_emul.hh" +#include "sim/system.hh" + +using namespace std; +using namespace PowerISA; + +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + TypedBufferArg name(process->getSyscallArg(tc, 0)); + + strcpy(name->sysname, "Linux"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "2.6.16.19"); + strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); + strcpy(name->machine, "power"); + + name.copyOut(tc->getMemPort()); + return 0; +} + +SyscallDesc PowerLinuxProcess::syscallDescs[] = { + /* 0 */ SyscallDesc("syscall", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), + /* 2 */ SyscallDesc("fork", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), + /* 4 */ SyscallDesc("write", writeFunc), + /* 5 */ SyscallDesc("open", openFunc), + /* 6 */ SyscallDesc("close", closeFunc), + /* 7 */ SyscallDesc("waitpid", unimplementedFunc), //??? + /* 8 */ SyscallDesc("creat", unimplementedFunc), + /* 9 */ SyscallDesc("link", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), + /* 11 */ SyscallDesc("execve", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 13 */ SyscallDesc("time", timeFunc), + /* 14 */ SyscallDesc("mknod", unimplementedFunc), + /* 15 */ SyscallDesc("chmod", chmodFunc), + /* 16 */ SyscallDesc("lchown", chownFunc), + /* 17 */ SyscallDesc("break", brkFunc), //??? + /* 18 */ SyscallDesc("unused#18", unimplementedFunc), //??? + /* 19 */ SyscallDesc("lseek", lseekFunc), + /* 20 */ SyscallDesc("getpid", getpidFunc), + /* 21 */ SyscallDesc("mount", unimplementedFunc), + /* 22 */ SyscallDesc("umount", unimplementedFunc), + /* 23 */ SyscallDesc("setuid", setuidFunc), + /* 24 */ SyscallDesc("getuid", getuidFunc), + /* 25 */ SyscallDesc("stime", unimplementedFunc), + /* 26 */ SyscallDesc("ptrace", unimplementedFunc), + /* 27 */ SyscallDesc("alarm", unimplementedFunc), + /* 28 */ SyscallDesc("unused#28", unimplementedFunc), + /* 29 */ SyscallDesc("pause", unimplementedFunc), + /* 30 */ SyscallDesc("utime", unimplementedFunc), + /* 31 */ SyscallDesc("stty", unimplementedFunc), + /* 32 */ SyscallDesc("gtty", unimplementedFunc), + /* 33 */ SyscallDesc("access", unimplementedFunc), + /* 34 */ SyscallDesc("nice", unimplementedFunc), + /* 35 */ SyscallDesc("ftime", unimplementedFunc), + /* 36 */ SyscallDesc("sync", unimplementedFunc), + /* 37 */ SyscallDesc("kill", ignoreFunc), + /* 38 */ SyscallDesc("rename", renameFunc), + /* 39 */ SyscallDesc("mkdir", unimplementedFunc), + /* 40 */ SyscallDesc("rmdir", unimplementedFunc), + /* 41 */ SyscallDesc("dup", dupFunc), + /* 42 */ SyscallDesc("pipe", unimplementedFunc), + /* 43 */ SyscallDesc("times", timesFunc), + /* 44 */ SyscallDesc("prof", unimplementedFunc), + /* 45 */ SyscallDesc("brk", brkFunc), + /* 46 */ SyscallDesc("setgid", unimplementedFunc), + /* 47 */ SyscallDesc("getgid", getgidFunc), + /* 48 */ SyscallDesc("signal", ignoreFunc), + /* 49 */ SyscallDesc("geteuid", geteuidFunc), + /* 50 */ SyscallDesc("getegid", getegidFunc), + /* 51 */ SyscallDesc("acct", unimplementedFunc), + /* 52 */ SyscallDesc("umount2", unimplementedFunc), + /* 53 */ SyscallDesc("lock", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", ioctlFunc), + /* 55 */ SyscallDesc("fcntl", fcntlFunc), + /* 56 */ SyscallDesc("mpx", unimplementedFunc), + /* 57 */ SyscallDesc("setpgid", unimplementedFunc), + /* 58 */ SyscallDesc("ulimit", unimplementedFunc), + /* 59 */ SyscallDesc("unused#59", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), + /* 61 */ SyscallDesc("chroot", unimplementedFunc), + /* 62 */ SyscallDesc("ustat", unimplementedFunc), + /* 63 */ SyscallDesc("dup2", unimplementedFunc), + /* 64 */ SyscallDesc("getppid", getpagesizeFunc), + /* 65 */ SyscallDesc("getpgrp", unimplementedFunc), + /* 66 */ SyscallDesc("setsid", unimplementedFunc), + /* 67 */ SyscallDesc("sigaction",unimplementedFunc), + /* 68 */ SyscallDesc("sgetmask", unimplementedFunc), + /* 69 */ SyscallDesc("ssetmask", unimplementedFunc), + /* 70 */ SyscallDesc("setreuid", unimplementedFunc), + /* 71 */ SyscallDesc("setregid", unimplementedFunc), + /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc), + /* 73 */ SyscallDesc("sigpending", unimplementedFunc), + /* 74 */ SyscallDesc("sethostname", ignoreFunc), + /* 75 */ SyscallDesc("setrlimit", ignoreFunc), + /* 76 */ SyscallDesc("getrlimit", unimplementedFunc), + /* 77 */ SyscallDesc("getrusage", ignoreFunc), + /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc), + /* 79 */ SyscallDesc("settimeofday", unimplementedFunc), + /* 80 */ SyscallDesc("getgroups", unimplementedFunc), + /* 81 */ SyscallDesc("setgroups", unimplementedFunc), + /* 82 */ SyscallDesc("reserved#82", unimplementedFunc), + /* 83 */ SyscallDesc("symlink", unimplementedFunc), + /* 84 */ SyscallDesc("unused#84", unimplementedFunc), + /* 85 */ SyscallDesc("readlink", unimplementedFunc), + /* 86 */ SyscallDesc("uselib", unimplementedFunc), + /* 87 */ SyscallDesc("swapon", gethostnameFunc), + /* 88 */ SyscallDesc("reboot", unimplementedFunc), + /* 89 */ SyscallDesc("readdir", unimplementedFunc), + /* 90 */ SyscallDesc("mmap", mmapFunc), + /* 91 */ SyscallDesc("munmap",munmapFunc), + /* 92 */ SyscallDesc("truncate", truncateFunc), + /* 93 */ SyscallDesc("ftruncate", ftruncateFunc), + /* 94 */ SyscallDesc("fchmod", unimplementedFunc), + /* 95 */ SyscallDesc("fchown", unimplementedFunc), + /* 96 */ SyscallDesc("getpriority", unimplementedFunc), + /* 97 */ SyscallDesc("setpriority", unimplementedFunc), + /* 98 */ SyscallDesc("profil", unimplementedFunc), + /* 99 */ SyscallDesc("statfs", unimplementedFunc), + /* 100 */ SyscallDesc("fstatfs", unimplementedFunc), + /* 101 */ SyscallDesc("ioperm", unimplementedFunc), + /* 102 */ SyscallDesc("socketcall", unimplementedFunc), + /* 103 */ SyscallDesc("syslog", unimplementedFunc), + /* 104 */ SyscallDesc("setitimer", unimplementedFunc), + /* 105 */ SyscallDesc("getitimer", unimplementedFunc), + /* 106 */ SyscallDesc("stat", statFunc), + /* 107 */ SyscallDesc("lstat", unimplementedFunc), + /* 108 */ SyscallDesc("fstat", fstatFunc), + /* 109 */ SyscallDesc("unused#109", unimplementedFunc), + /* 110 */ SyscallDesc("iopl", unimplementedFunc), + /* 111 */ SyscallDesc("vhangup", unimplementedFunc), + /* 112 */ SyscallDesc("idle", ignoreFunc), + /* 113 */ SyscallDesc("vm86", unimplementedFunc), + /* 114 */ SyscallDesc("wait4", unimplementedFunc), + /* 115 */ SyscallDesc("swapoff", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 117 */ SyscallDesc("ipc", unimplementedFunc), + /* 118 */ SyscallDesc("fsync", unimplementedFunc), + /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), + /* 120 */ SyscallDesc("clone", unimplementedFunc), + /* 121 */ SyscallDesc("setdomainname", unimplementedFunc), + /* 122 */ SyscallDesc("uname", unameFunc), + /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc), + /* 124 */ SyscallDesc("adjtimex", unimplementedFunc), + /* 125 */ SyscallDesc("mprotect", ignoreFunc), + /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc), + /* 127 */ SyscallDesc("create_module", unimplementedFunc), + /* 128 */ SyscallDesc("init_module", unimplementedFunc), + /* 129 */ SyscallDesc("delete_module", unimplementedFunc), + /* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc), + /* 131 */ SyscallDesc("quotactl", unimplementedFunc), + /* 132 */ SyscallDesc("getpgid", unimplementedFunc), + /* 133 */ SyscallDesc("fchdir", unimplementedFunc), + /* 134 */ SyscallDesc("bdflush", unimplementedFunc), + /* 135 */ SyscallDesc("sysfs", unimplementedFunc), + /* 136 */ SyscallDesc("personality", unimplementedFunc), + /* 137 */ SyscallDesc("afs_syscall", unimplementedFunc), + /* 138 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 139 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 140 */ SyscallDesc("llseek", _llseekFunc), + /* 141 */ SyscallDesc("getdents", unimplementedFunc), + /* 142 */ SyscallDesc("newselect", unimplementedFunc), + /* 143 */ SyscallDesc("flock", unimplementedFunc), + /* 144 */ SyscallDesc("msync", unimplementedFunc), + /* 145 */ SyscallDesc("readv", unimplementedFunc), + /* 146 */ SyscallDesc("writev", writevFunc), + /* 147 */ SyscallDesc("getsid", unimplementedFunc), + /* 148 */ SyscallDesc("fdatasync", unimplementedFunc), + /* 149 */ SyscallDesc("sysctl", unimplementedFunc), + /* 150 */ SyscallDesc("mlock", unimplementedFunc), + /* 151 */ SyscallDesc("munlock", unimplementedFunc), + /* 152 */ SyscallDesc("mlockall", unimplementedFunc), + /* 153 */ SyscallDesc("munlockall", unimplementedFunc), + /* 154 */ SyscallDesc("sched_setparam", unimplementedFunc), + /* 155 */ SyscallDesc("sched_getparam", unimplementedFunc), + /* 156 */ SyscallDesc("sched_setscheduler", unimplementedFunc), + /* 157 */ SyscallDesc("sched_getscheduler", unimplementedFunc), + /* 158 */ SyscallDesc("sched_yield", unimplementedFunc), + /* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), + /* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), + /* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), + /* 162 */ SyscallDesc("nanosleep", unimplementedFunc), + /* 163 */ SyscallDesc("mremap", unimplementedFunc), + /* 164 */ SyscallDesc("setresuid", unimplementedFunc), + /* 165 */ SyscallDesc("getresuid", unimplementedFunc), + /* 166 */ SyscallDesc("vm862", unimplementedFunc), + /* 167 */ SyscallDesc("query_module", unimplementedFunc), + /* 168 */ SyscallDesc("poll", unimplementedFunc), + /* 169 */ SyscallDesc("nfsservctl", unimplementedFunc), + /* 170 */ SyscallDesc("setresgid", unimplementedFunc), + /* 171 */ SyscallDesc("getresgid", unimplementedFunc), + /* 172 */ SyscallDesc("prctl", unimplementedFunc), + /* 173 */ SyscallDesc("rt_sigaction", ignoreFunc), + /* 174 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), + /* 175 */ SyscallDesc("unknown#175", unimplementedFunc), + /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc), + /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), + /* 178 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc), + /* 179 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), + /* 180 */ SyscallDesc("pread64", unimplementedFunc), + /* 181 */ SyscallDesc("pwrite64", unimplementedFunc), + /* 182 */ SyscallDesc("chown", unimplementedFunc), + /* 183 */ SyscallDesc("getcwd", unimplementedFunc), + /* 184 */ SyscallDesc("capget", unimplementedFunc), + /* 185 */ SyscallDesc("capset", unimplementedFunc), + /* 186 */ SyscallDesc("sigaltstack", unimplementedFunc), + /* 187 */ SyscallDesc("sendfile", unimplementedFunc), + /* 188 */ SyscallDesc("getpmsg", unimplementedFunc), + /* 189 */ SyscallDesc("putpmsg", unimplementedFunc), + /* 190 */ SyscallDesc("ugetrlimit", ignoreFunc), + /* 191 */ SyscallDesc("getrlimit", unimplementedFunc), + /* 192 */ SyscallDesc("mmap2", mmapFunc), + /* 193 */ SyscallDesc("truncate64", unimplementedFunc), + /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func), + /* 195 */ SyscallDesc("stat64", stat64Func), + /* 196 */ SyscallDesc("lstat64", lstat64Func), + /* 197 */ SyscallDesc("fstat64", fstat64Func), + /* 198 */ SyscallDesc("lchown", unimplementedFunc), + /* 199 */ SyscallDesc("getuid", getuidFunc), + /* 200 */ SyscallDesc("getgid", getgidFunc), + /* 201 */ SyscallDesc("geteuid", geteuidFunc), + /* 202 */ SyscallDesc("getegid", getegidFunc), + /* 203 */ SyscallDesc("setreuid", unimplementedFunc), + /* 204 */ SyscallDesc("fcntl64", fcntl64Func), + /* 205 */ SyscallDesc("getgroups", unimplementedFunc), + /* 206 */ SyscallDesc("setgroups", unimplementedFunc), + /* 207 */ SyscallDesc("fchown", unimplementedFunc), + /* 208 */ SyscallDesc("setresuid", unimplementedFunc), + /* 209 */ SyscallDesc("getresuid", unimplementedFunc), + /* 210 */ SyscallDesc("setresgid", unimplementedFunc), + /* 211 */ SyscallDesc("getresgid", unimplementedFunc), + /* 212 */ SyscallDesc("chown", unimplementedFunc), + /* 213 */ SyscallDesc("setuid", unimplementedFunc), + /* 214 */ SyscallDesc("setgid", unimplementedFunc), + /* 215 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 216 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 217 */ SyscallDesc("getdents64", unimplementedFunc), + /* 218 */ SyscallDesc("pivot_root", unimplementedFunc), + /* 219 */ SyscallDesc("mincore", unimplementedFunc), + /* 220 */ SyscallDesc("madvise", unimplementedFunc), + /* 221 */ SyscallDesc("unknown#221", unimplementedFunc), + /* 222 */ SyscallDesc("tux", unimplementedFunc), + /* 223 */ SyscallDesc("unknown#223", unimplementedFunc), + /* 224 */ SyscallDesc("gettid", unimplementedFunc), + /* 225 */ SyscallDesc("readahead", unimplementedFunc), + /* 226 */ SyscallDesc("setxattr", unimplementedFunc), + /* 227 */ SyscallDesc("lsetxattr", unimplementedFunc), + /* 228 */ SyscallDesc("fsetxattr", unimplementedFunc), + /* 229 */ SyscallDesc("getxattr", unimplementedFunc), + /* 230 */ SyscallDesc("lgetxattr", unimplementedFunc), + /* 231 */ SyscallDesc("fgetxattr", unimplementedFunc), + /* 232 */ SyscallDesc("listxattr", unimplementedFunc), + /* 233 */ SyscallDesc("llistxattr", unimplementedFunc), + /* 234 */ SyscallDesc("exit_group", exitGroupFunc), + /* 235 */ SyscallDesc("removexattr", unimplementedFunc), + /* 236 */ SyscallDesc("lremovexattr", unimplementedFunc), + /* 237 */ SyscallDesc("fremovexattr", unimplementedFunc), + /* 238 */ SyscallDesc("tkill", unimplementedFunc), + /* 239 */ SyscallDesc("sendfile64", unimplementedFunc), + /* 240 */ SyscallDesc("futex", unimplementedFunc), + /* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc), + /* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc), + /* 243 */ SyscallDesc("io_setup", unimplementedFunc), + /* 244 */ SyscallDesc("io_destory", unimplementedFunc), + /* 245 */ SyscallDesc("io_getevents", unimplementedFunc), + /* 246 */ SyscallDesc("io_submit", unimplementedFunc), + /* 247 */ SyscallDesc("io_cancel", unimplementedFunc), + /* 248 */ SyscallDesc("unknown#248", unimplementedFunc), + /* 249 */ SyscallDesc("lookup_dcookie", unimplementedFunc), + /* 250 */ SyscallDesc("epoll_create", unimplementedFunc), + /* 251 */ SyscallDesc("epoll_ctl", unimplementedFunc), + /* 252 */ SyscallDesc("epoll_wait", unimplementedFunc), + /* 253 */ SyscallDesc("remap_file_pages", unimplementedFunc), + /* 254 */ SyscallDesc("set_thread_area", unimplementedFunc), + /* 255 */ SyscallDesc("get_thread_area", unimplementedFunc), + /* 256 */ SyscallDesc("set_tid_address", unimplementedFunc), + /* 257 */ SyscallDesc("timer_create", unimplementedFunc), + /* 258 */ SyscallDesc("timer_settime", unimplementedFunc), + /* 259 */ SyscallDesc("timer_gettime", unimplementedFunc), + /* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc), + /* 261 */ SyscallDesc("timer_delete", unimplementedFunc), + /* 262 */ SyscallDesc("clock_settime", unimplementedFunc), + /* 263 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 264 */ SyscallDesc("clock_getres", unimplementedFunc), + /* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc), + /* 266 */ SyscallDesc("statfs64", unimplementedFunc), + /* 267 */ SyscallDesc("fstatfs64", unimplementedFunc), + /* 268 */ SyscallDesc("tgkill", unimplementedFunc), + /* 269 */ SyscallDesc("utimes", unimplementedFunc), + /* 270 */ SyscallDesc("arm_fadvise64_64", unimplementedFunc), + /* 271 */ SyscallDesc("pciconfig_iobase", unimplementedFunc), + /* 272 */ SyscallDesc("pciconfig_read", unimplementedFunc), + /* 273 */ SyscallDesc("pciconfig_write", unimplementedFunc), + /* 274 */ SyscallDesc("mq_open", unimplementedFunc), + /* 275 */ SyscallDesc("mq_unlink", unimplementedFunc), + /* 276 */ SyscallDesc("mq_timedsend", unimplementedFunc), + /* 277 */ SyscallDesc("mq_timedreceive", unimplementedFunc), + /* 278 */ SyscallDesc("mq_notify", unimplementedFunc), + /* 279 */ SyscallDesc("mq_getsetattr", unimplementedFunc), + /* 280 */ SyscallDesc("waitid", unimplementedFunc), + /* 281 */ SyscallDesc("socket", unimplementedFunc), + /* 282 */ SyscallDesc("bind", unimplementedFunc), + /* 283 */ SyscallDesc("connect", unimplementedFunc), + /* 284 */ SyscallDesc("listen", unimplementedFunc), + /* 285 */ SyscallDesc("accept", unimplementedFunc), + /* 286 */ SyscallDesc("getsockname", unimplementedFunc), + /* 287 */ SyscallDesc("getpeername", unimplementedFunc), + /* 288 */ SyscallDesc("socketpair", unimplementedFunc), + /* 289 */ SyscallDesc("send", unimplementedFunc), + /* 290 */ SyscallDesc("sendto", unimplementedFunc), + /* 291 */ SyscallDesc("recv", unimplementedFunc), + /* 292 */ SyscallDesc("recvfrom", unimplementedFunc), + /* 293 */ SyscallDesc("shutdown", unimplementedFunc), + /* 294 */ SyscallDesc("setsockopt", unimplementedFunc), + /* 295 */ SyscallDesc("getsockopt", unimplementedFunc), + /* 296 */ SyscallDesc("sendmsg", unimplementedFunc), + /* 297 */ SyscallDesc("rcvmsg", unimplementedFunc), + /* 298 */ SyscallDesc("semop", unimplementedFunc), + /* 299 */ SyscallDesc("semget", unimplementedFunc), + /* 300 */ SyscallDesc("semctl", unimplementedFunc), + /* 301 */ SyscallDesc("msgsend", unimplementedFunc), + /* 302 */ SyscallDesc("msgrcv", unimplementedFunc), + /* 303 */ SyscallDesc("msgget", unimplementedFunc), + /* 304 */ SyscallDesc("msgctl", unimplementedFunc), + /* 305 */ SyscallDesc("shmat", unimplementedFunc), + /* 306 */ SyscallDesc("shmdt", unimplementedFunc), + /* 307 */ SyscallDesc("shmget", unimplementedFunc), + /* 308 */ SyscallDesc("shmctl", unimplementedFunc), + /* 309 */ SyscallDesc("add_key", unimplementedFunc), + /* 310 */ SyscallDesc("request_key", unimplementedFunc), + /* 311 */ SyscallDesc("keyctl", unimplementedFunc), + /* 312 */ SyscallDesc("semtimedop", unimplementedFunc), + /* 313 */ SyscallDesc("vserver", unimplementedFunc), + /* 314 */ SyscallDesc("ioprio_set", unimplementedFunc), + /* 315 */ SyscallDesc("ioprio_get", unimplementedFunc), + /* 316 */ SyscallDesc("inotify_init", unimplementedFunc), + /* 317 */ SyscallDesc("inotify_add_watch", unimplementedFunc), + /* 318 */ SyscallDesc("inotify_rm_watch", unimplementedFunc), + /* 319 */ SyscallDesc("mbind", unimplementedFunc), + /* 320 */ SyscallDesc("get_mempolicy", unimplementedFunc), + /* 321 */ SyscallDesc("set_mempolicy", unimplementedFunc), + /* 322 */ SyscallDesc("openat", unimplementedFunc), + /* 323 */ SyscallDesc("mkdirat", unimplementedFunc), + /* 324 */ SyscallDesc("mknodat", unimplementedFunc), + /* 325 */ SyscallDesc("fchownat", unimplementedFunc), + /* 326 */ SyscallDesc("futimesat", unimplementedFunc), + /* 327 */ SyscallDesc("fstatat64", unimplementedFunc), + /* 328 */ SyscallDesc("unlinkat", unimplementedFunc), + /* 329 */ SyscallDesc("renameat", unimplementedFunc), + /* 330 */ SyscallDesc("linkat", unimplementedFunc), + /* 331 */ SyscallDesc("symlinkat", unimplementedFunc), + /* 332 */ SyscallDesc("readlinkat", unimplementedFunc), + /* 333 */ SyscallDesc("fchmodat", unimplementedFunc), + /* 334 */ SyscallDesc("faccessat", unimplementedFunc), + /* 335 */ SyscallDesc("pselect6", unimplementedFunc), + /* 336 */ SyscallDesc("ppoll", unimplementedFunc), + /* 337 */ SyscallDesc("unshare", unimplementedFunc), + /* 338 */ SyscallDesc("set_robust_list", unimplementedFunc), + /* 339 */ SyscallDesc("get_robust_list", unimplementedFunc), + /* 340 */ SyscallDesc("splice", unimplementedFunc), + /* 341 */ SyscallDesc("arm_sync_file_range", unimplementedFunc), + /* 342 */ SyscallDesc("tee", unimplementedFunc), + /* 343 */ SyscallDesc("vmsplice", unimplementedFunc), + /* 344 */ SyscallDesc("move_pages", unimplementedFunc), + /* 345 */ SyscallDesc("getcpu", unimplementedFunc), + /* 346 */ SyscallDesc("epoll_pwait", unimplementedFunc), +}; + +PowerLinuxProcess::PowerLinuxProcess(LiveProcessParams * params, + ObjectFile *objFile) + : PowerLiveProcess(params, objFile), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) +{ +} + +SyscallDesc* +PowerLinuxProcess::getDesc(int callnum) +{ + if (callnum < 0 || callnum > Num_Syscall_Descs) + return NULL; + + return &syscallDescs[callnum]; +} + +void +PowerLinuxProcess::startup() +{ + PowerLiveProcess::startup(); +} + +PowerISA::IntReg +PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int i) +{ + // Linux apparently allows more parameter than the ABI says it should. + // This limit may need to be increased even further. + assert(i < 6); + return tc->readIntReg(ArgumentReg0 + i); +} + +void +PowerLinuxProcess::setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val) +{ + // Linux apparently allows more parameter than the ABI says it should. + // This limit may need to be increased even further. + assert(i < 6); + tc->setIntReg(ArgumentReg0 + i, val); +} diff --git a/src/arch/power/linux/process.hh b/src/arch/power/linux/process.hh new file mode 100644 index 0000000000..78b0eef7fe --- /dev/null +++ b/src/arch/power/linux/process.hh @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + * Timothy M. Jones + */ + +#ifndef __POWER_LINUX_PROCESS_HH__ +#define __POWER_LINUX_PROCESS_HH__ + +#include "arch/power/process.hh" + + +/// A process with emulated PPC/Linux syscalls. +class PowerLinuxProcess : public PowerLiveProcess +{ + public: + PowerLinuxProcess(LiveProcessParams * params, ObjectFile *objFile); + + virtual SyscallDesc* getDesc(int callnum); + + void startup(); + + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); + + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; + + const int Num_Syscall_Descs; +}; + +#endif // __POWER_LINUX_PROCESS_HH__ diff --git a/src/arch/power/locked_mem.hh b/src/arch/power/locked_mem.hh new file mode 100644 index 0000000000..56ab1d4a0e --- /dev/null +++ b/src/arch/power/locked_mem.hh @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_LOCKED_MEM_HH__ +#define __ARCH_POWER_LOCKED_MEM_HH__ + +/** + * @file + * + * ISA-specific helper functions for locked memory accesses. + */ + +#include "mem/request.hh" + +namespace PowerISA +{ + +template +inline void +handleLockedRead(XC *xc, Request *req) +{ +} + +template +inline bool +handleLockedWrite(XC *xc, Request *req) +{ + return true; +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_LOCKED_MEM_HH__ diff --git a/src/arch/power/microcode_rom.hh b/src/arch/power/microcode_rom.hh new file mode 100644 index 0000000000..e35db5112e --- /dev/null +++ b/src/arch/power/microcode_rom.hh @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_MICROCODE_ROM_HH__ +#define __ARCH_POWER_MICROCODE_ROM_HH__ + +#include "sim/microcode_rom.hh" + +namespace PowerISA +{ + +using ::MicrocodeRom; + +} // PowerISA namespace + +#endif // __ARCH_POWER_MICROCODE_ROM_HH__ diff --git a/src/arch/power/miscregs.hh b/src/arch/power/miscregs.hh new file mode 100644 index 0000000000..cd9815b2a7 --- /dev/null +++ b/src/arch/power/miscregs.hh @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_MISCREGS_HH__ +#define __ARCH_POWER_MISCREGS_HH__ + +#include "base/bitunion.hh" + +namespace PowerISA +{ + +enum MiscRegIndex { + NUM_MISCREGS = 0 +}; + +const char * const miscRegName[NUM_MISCREGS] = { +}; + +BitUnion32(Cr) + Bitfield<31,28> cr0; + Bitfield<27,24> cr1; +EndBitUnion(Cr) + +BitUnion32(Xer) + Bitfield<31> so; + Bitfield<30> ov; + Bitfield<29> ca; +EndBitUnion(Xer) + +BitUnion32(Fpscr) + Bitfield<31> fx; + Bitfield<30> fex; + Bitfield<29> vx; + Bitfield<28> ox; + Bitfield<27> ux; + Bitfield<26> zx; + Bitfield<25> xx; + Bitfield<24> vxsnan; + Bitfield<23> vxisi; + Bitfield<22> vxidi; + Bitfield<21> vxzdz; + Bitfield<20> vximz; + Bitfield<19> vxvc; + Bitfield<18> fr; + Bitfield<17> fi; + SubBitUnion(fprf, 16, 12) + Bitfield<16> c; + SubBitUnion(fpcc, 15, 12) + Bitfield<15> fl; + Bitfield<14> fg; + Bitfield<13> fe; + Bitfield<12> fu; + EndSubBitUnion(fpcc) + EndSubBitUnion(fprf) + Bitfield<10> vxsqrt; + Bitfield<9> vxcvi; + Bitfield<8> ve; + Bitfield<7> oe; + Bitfield<6> ue; + Bitfield<5> ze; + Bitfield<4> xe; + Bitfield<3> ni; + Bitfield<2,1> rn; +EndBitUnion(Fpscr) + +}; // PowerISA namespace + +#endif // __ARCH_POWER_MISCREGS_HH__ diff --git a/src/arch/power/mmaped_ipr.hh b/src/arch/power/mmaped_ipr.hh new file mode 100644 index 0000000000..bd1ea10b35 --- /dev/null +++ b/src/arch/power/mmaped_ipr.hh @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_MMAPED_IPR_HH__ +#define __ARCH_POWER_MMAPED_IPR_HH__ + +/** + * @file + * + * ISA-specific helper functions for memory mapped IPR accesses. + */ + +#include "base/misc.hh" +#include "mem/packet.hh" + +class ThreadContext; + +namespace PowerISA +{ + +inline Tick +handleIprRead(ThreadContext *xc, Packet *pkt) +{ + panic("No implementation for handleIprRead in POWER\n"); +} + +inline Tick +handleIprWrite(ThreadContext *xc, Packet *pkt) +{ + panic("No implementation for handleIprWrite in POWER\n"); +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_MMAPED_IPR_HH__ diff --git a/src/arch/power/pagetable.cc b/src/arch/power/pagetable.cc new file mode 100644 index 0000000000..862404578b --- /dev/null +++ b/src/arch/power/pagetable.cc @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Jaidev Patwardhan + * Stephen Hines + * Timothy M. Jones + */ + +#include "arch/power/pagetable.hh" +#include "sim/serialize.hh" + +namespace PowerISA +{ + +void +PTE::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(Mask); + SERIALIZE_SCALAR(VPN); + SERIALIZE_SCALAR(asid); + SERIALIZE_SCALAR(G); + SERIALIZE_SCALAR(PFN0); + SERIALIZE_SCALAR(D0); + SERIALIZE_SCALAR(V0); + SERIALIZE_SCALAR(C0); + SERIALIZE_SCALAR(PFN1); + SERIALIZE_SCALAR(D1); + SERIALIZE_SCALAR(V1); + SERIALIZE_SCALAR(C1); + SERIALIZE_SCALAR(AddrShiftAmount); + SERIALIZE_SCALAR(OffsetMask); +} + +void +PTE::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(Mask); + UNSERIALIZE_SCALAR(VPN); + UNSERIALIZE_SCALAR(asid); + UNSERIALIZE_SCALAR(G); + UNSERIALIZE_SCALAR(PFN0); + UNSERIALIZE_SCALAR(D0); + UNSERIALIZE_SCALAR(V0); + UNSERIALIZE_SCALAR(C0); + UNSERIALIZE_SCALAR(PFN1); + UNSERIALIZE_SCALAR(D1); + UNSERIALIZE_SCALAR(V1); + UNSERIALIZE_SCALAR(C1); + UNSERIALIZE_SCALAR(AddrShiftAmount); + UNSERIALIZE_SCALAR(OffsetMask); +} + +} // PowerISA namespace diff --git a/src/arch/power/pagetable.hh b/src/arch/power/pagetable.hh new file mode 100644 index 0000000000..bd2b9d3978 --- /dev/null +++ b/src/arch/power/pagetable.hh @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Jaidev Patwardhan + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_PAGETABLE_H__ +#define __ARCH_POWER_PAGETABLE_H__ + +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" +#include "arch/power/vtophys.hh" +#include "config/full_system.hh" + +namespace PowerISA { + +struct VAddr +{ + static const int ImplBits = 43; + static const Addr ImplMask = (ULL(1) << ImplBits) - 1; + static const Addr UnImplMask = ~ImplMask; + + Addr addr; + + VAddr(Addr a) + : addr(a) + {} + + operator Addr() const + { + return addr; + } + + const VAddr + &operator=(Addr a) + { + addr = a; + return *this; + } + + Addr + vpn() const + { + return (addr & ImplMask) >> PageShift; + } + + Addr + page() const + { + return addr & Page_Mask; + } + + Addr + offset() const + { + return addr & PageOffset; + } + + Addr + level3() const + { + return PowerISA::PteAddr(addr >> PageShift); + } + + Addr + level2() const + { + return PowerISA::PteAddr(addr >> (NPtePageShift + PageShift)); + } + + Addr + level1() const + { + return PowerISA::PteAddr(addr >> (2 * NPtePageShift + PageShift)); + } +}; + +// ITB/DTB page table entry +struct PTE +{ + // What parts of the VAddr (from bits 28..11) should be used in + // translation (includes Mask and MaskX from PageMask) + Addr Mask; + + // Virtual Page Number (/2) (Includes VPN2 + VPN2X .. bits 31..11 + // from EntryHi) + Addr VPN; + + // Address Space ID (8 bits) // Lower 8 bits of EntryHi + uint8_t asid; + + // Global Bit - Obtained by an *AND* of EntryLo0 and EntryLo1 G bit + bool G; + + /* Contents of Entry Lo0 */ + Addr PFN0; // Physical Frame Number - Even + bool D0; // Even entry Dirty Bit + bool V0; // Even entry Valid Bit + uint8_t C0; // Cache Coherency Bits - Even + + /* Contents of Entry Lo1 */ + Addr PFN1; // Physical Frame Number - Odd + bool D1; // Odd entry Dirty Bit + bool V1; // Odd entry Valid Bit + uint8_t C1; // Cache Coherency Bits (3 bits) + + // The next few variables are put in as optimizations to reduce TLB + // lookup overheads. For a given Mask, what is the address shift amount + // and what is the OffsetMask + int AddrShiftAmount; + int OffsetMask; + + bool + Valid() + { + return (V0 | V1); + }; + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_PAGETABLE_H__ + diff --git a/src/arch/power/predecoder.hh b/src/arch/power/predecoder.hh new file mode 100644 index 0000000000..1f3ac41cb3 --- /dev/null +++ b/src/arch/power/predecoder.hh @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_ARM_PREDECODER_HH__ +#define __ARCH_ARM_PREDECODER_HH__ + +#include "arch/power/types.hh" +#include "base/misc.hh" +#include "base/types.hh" + +class ThreadContext; + +namespace PowerISA +{ + +class Predecoder +{ + protected: + ThreadContext * tc; + + // The extended machine instruction being generated + ExtMachInst emi; + + public: + Predecoder(ThreadContext * _tc) + : tc(_tc) + { + } + + ThreadContext * + getTC() + { + return tc; + } + + void + setTC(ThreadContext * _tc) + { + tc = _tc; + } + + void + process() + { + } + + void + reset() + { + } + + // Use this to give data to the predecoder. This should be used + // when there is control flow. + void + moreBytes(Addr pc, Addr fetchPC, MachInst inst) + { + emi = inst; + } + + // Use this to give data to the predecoder. This should be used + // when instructions are executed in order. + void + moreBytes(MachInst machInst) + { + moreBytes(0, 0, machInst); + } + + bool + needMoreBytes() + { + return true; + } + + bool + extMachInstReady() + { + return true; + } + + // This returns a constant reference to the ExtMachInst to avoid a copy + const ExtMachInst & + getExtMachInst() + { + return emi; + } +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_PREDECODER_HH__ diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc new file mode 100644 index 0000000000..8828a1a934 --- /dev/null +++ b/src/arch/power/process.cc @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + * Timothy M. Jones + */ + +#include "arch/power/isa_traits.hh" +#include "arch/power/process.hh" +#include "arch/power/types.hh" +#include "base/loader/elf_object.hh" +#include "base/loader/object_file.hh" +#include "base/misc.hh" +#include "cpu/thread_context.hh" +#include "mem/page_table.hh" +#include "mem/translating_port.hh" +#include "sim/process_impl.hh" +#include "sim/system.hh" + +using namespace std; +using namespace PowerISA; + +PowerLiveProcess::PowerLiveProcess(LiveProcessParams *params, + ObjectFile *objFile) + : LiveProcess(params, objFile) +{ + stack_base = 0xbf000000L; + + // Set pointer for next thread stack. Reserve 8M for main stack. + next_thread_stack_base = stack_base - (8 * 1024 * 1024); + + // Set up break point (Top of Heap) + brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); + brk_point = roundUp(brk_point, VMPageSize); + + // Set up region for mmaps. For now, start at bottom of kuseg space. + mmap_start = mmap_end = 0x70000000L; +} + +void +PowerLiveProcess::startup() +{ + argsInit(MachineBytes, VMPageSize); +} + +void +PowerLiveProcess::argsInit(int intSize, int pageSize) +{ + typedef AuxVector auxv_t; + std::vector auxv; + + string filename; + if (argv.size() < 1) + filename = ""; + else + filename = argv[0]; + + //We want 16 byte alignment + uint64_t align = 16; + + // Overloaded argsInit so that we can fine-tune for POWER architecture + Process::startup(); + + // load object file into target memory + objFile->loadSections(initVirtMem); + + //Setup the auxilliary vectors. These will already have endian conversion. + //Auxilliary vectors are loaded only for elf formatted executables. + ElfObject * elfObject = dynamic_cast(objFile); + if (elfObject) { + uint32_t features = 0; + + //Bits which describe the system hardware capabilities + //XXX Figure out what these should be + auxv.push_back(auxv_t(M5_AT_HWCAP, features)); + //The system page size + auxv.push_back(auxv_t(M5_AT_PAGESZ, PowerISA::VMPageSize)); + //Frequency at which times() increments + auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64)); + // For statically linked executables, this is the virtual address of the + // program header tables if they appear in the executable image + auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable())); + // This is the size of a program header entry from the elf file. + auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize())); + // This is the number of program headers from the original elf file. + auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount())); + //This is the address of the elf "interpreter", It should be set + //to 0 for regular executables. It should be something else + //(not sure what) for dynamic libraries. + auxv.push_back(auxv_t(M5_AT_BASE, 0)); + + //XXX Figure out what this should be. + auxv.push_back(auxv_t(M5_AT_FLAGS, 0)); + //The entry point to the program + auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint())); + //Different user and group IDs + auxv.push_back(auxv_t(M5_AT_UID, uid())); + auxv.push_back(auxv_t(M5_AT_EUID, euid())); + auxv.push_back(auxv_t(M5_AT_GID, gid())); + auxv.push_back(auxv_t(M5_AT_EGID, egid())); + //Whether to enable "secure mode" in the executable + auxv.push_back(auxv_t(M5_AT_SECURE, 0)); + //The filename of the program + auxv.push_back(auxv_t(M5_AT_EXECFN, 0)); + //The string "v51" with unknown meaning + auxv.push_back(auxv_t(M5_AT_PLATFORM, 0)); + } + + //Figure out how big the initial stack nedes to be + + // A sentry NULL void pointer at the top of the stack. + int sentry_size = intSize; + + string platform = "v51"; + int platform_size = platform.size() + 1; + + // The aux vectors are put on the stack in two groups. The first group are + // the vectors that are generated as the elf is loaded. The second group + // are the ones that were computed ahead of time and include the platform + // string. + int aux_data_size = filename.size() + 1; + + int env_data_size = 0; + for (int i = 0; i < envp.size(); ++i) { + env_data_size += envp[i].size() + 1; + } + int arg_data_size = 0; + for (int i = 0; i < argv.size(); ++i) { + arg_data_size += argv[i].size() + 1; + } + + int info_block_size = + sentry_size + env_data_size + arg_data_size + + aux_data_size + platform_size; + + //Each auxilliary vector is two 4 byte words + int aux_array_size = intSize * 2 * (auxv.size() + 1); + + int envp_array_size = intSize * (envp.size() + 1); + int argv_array_size = intSize * (argv.size() + 1); + + int argc_size = intSize; + + //Figure out the size of the contents of the actual initial frame + int frame_size = + info_block_size + + aux_array_size + + envp_array_size + + argv_array_size + + argc_size; + + //There needs to be padding after the auxiliary vector data so that the + //very bottom of the stack is aligned properly. + int partial_size = frame_size; + int aligned_partial_size = roundUp(partial_size, align); + int aux_padding = aligned_partial_size - partial_size; + + int space_needed = frame_size + aux_padding; + + stack_min = stack_base - space_needed; + stack_min = roundDown(stack_min, align); + stack_size = stack_base - stack_min; + + // map memory + pTable->allocate(roundDown(stack_min, pageSize), + roundUp(stack_size, pageSize)); + + // map out initial stack contents + uint32_t sentry_base = stack_base - sentry_size; + uint32_t aux_data_base = sentry_base - aux_data_size; + uint32_t env_data_base = aux_data_base - env_data_size; + uint32_t arg_data_base = env_data_base - arg_data_size; + uint32_t platform_base = arg_data_base - platform_size; + uint32_t auxv_array_base = platform_base - aux_array_size - aux_padding; + uint32_t envp_array_base = auxv_array_base - envp_array_size; + uint32_t argv_array_base = envp_array_base - argv_array_size; + uint32_t argc_base = argv_array_base - argc_size; + + DPRINTF(Stack, "The addresses of items on the initial stack:\n"); + DPRINTF(Stack, "0x%x - aux data\n", aux_data_base); + DPRINTF(Stack, "0x%x - env data\n", env_data_base); + DPRINTF(Stack, "0x%x - arg data\n", arg_data_base); + DPRINTF(Stack, "0x%x - platform base\n", platform_base); + DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base); + DPRINTF(Stack, "0x%x - envp array\n", envp_array_base); + DPRINTF(Stack, "0x%x - argv array\n", argv_array_base); + DPRINTF(Stack, "0x%x - argc \n", argc_base); + DPRINTF(Stack, "0x%x - stack min\n", stack_min); + + // write contents to stack + + // figure out argc + uint32_t argc = argv.size(); + uint32_t guestArgc = PowerISA::htog(argc); + + //Write out the sentry void * + uint32_t sentry_NULL = 0; + initVirtMem->writeBlob(sentry_base, + (uint8_t*)&sentry_NULL, sentry_size); + + //Fix up the aux vectors which point to other data + for (int i = auxv.size() - 1; i >= 0; i--) { + if (auxv[i].a_type == M5_AT_PLATFORM) { + auxv[i].a_val = platform_base; + initVirtMem->writeString(platform_base, platform.c_str()); + } else if (auxv[i].a_type == M5_AT_EXECFN) { + auxv[i].a_val = aux_data_base; + initVirtMem->writeString(aux_data_base, filename.c_str()); + } + } + + //Copy the aux stuff + for (int x = 0; x < auxv.size(); x++) + { + initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize, + (uint8_t*)&(auxv[x].a_type), intSize); + initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize, + (uint8_t*)&(auxv[x].a_val), intSize); + } + //Write out the terminating zeroed auxilliary vector + const uint64_t zero = 0; + initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(), + (uint8_t*)&zero, 2 * intSize); + + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); + copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); + + initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); + + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + //Set the stack pointer register + tc->setIntReg(StackPointerReg, stack_min); + + Addr prog_entry = objFile->entryPoint(); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + + //Align the "stack_min" to a page boundary. + stack_min = roundDown(stack_min, pageSize); +} + +PowerISA::IntReg +PowerLiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 5); + return tc->readIntReg(ArgumentReg0 + i); +} + +void +PowerLiveProcess::setSyscallArg(ThreadContext *tc, + int i, PowerISA::IntReg val) +{ + assert(i < 5); + tc->setIntReg(ArgumentReg0 + i, val); +} + +void +PowerLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + tc->setIntReg(ReturnValueReg, return_value.value()); +} diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh new file mode 100644 index 0000000000..dae776c4c4 --- /dev/null +++ b/src/arch/power/process.hh @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + * Timothy M. Jones + */ + +#ifndef __POWER_PROCESS_HH__ +#define __POWER_PROCESS_HH__ + +#include +#include +#include "sim/process.hh" + +class LiveProcess; +class ObjectFile; +class System; + +class PowerLiveProcess : public LiveProcess +{ + protected: + PowerLiveProcess(LiveProcessParams * params, ObjectFile *objFile); + + void startup(); + + public: + void argsInit(int intSize, int pageSize); + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); +}; + +#endif // __POWER_PROCESS_HH__ + diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh new file mode 100644 index 0000000000..5bcca36419 --- /dev/null +++ b/src/arch/power/registers.hh @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_REGISTERS_HH__ +#define __ARCH_POWER_REGISTERS_HH__ + +#include "arch/power/max_inst_regs.hh" +#include "arch/power/miscregs.hh" + +namespace PowerISA { + +using PowerISAInst::MaxInstSrcRegs; +using PowerISAInst::MaxInstDestRegs; + +typedef uint8_t RegIndex; + +typedef uint64_t IntReg; + +// Floating point register file entry type +typedef uint64_t FloatRegBits; +typedef double FloatReg; +typedef uint64_t MiscReg; + +// Constants Related to the number of registers +const int NumIntArchRegs = 32; + +// CR, XER, LR, CTR, FPSCR, RSV, RSV-LEN, RSV-ADDR +// and zero register, which doesn't actually exist but needs a number +const int NumIntSpecialRegs = 9; +const int NumFloatArchRegs = 32; +const int NumFloatSpecialRegs = 0; +const int NumInternalProcRegs = 0; + +const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; +const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs; +const int NumMiscRegs = NUM_MISCREGS; + +// Semantically meaningful register indices +const int ReturnValueReg = 3; +const int ArgumentReg0 = 3; +const int ArgumentReg1 = 4; +const int ArgumentReg2 = 5; +const int ArgumentReg3 = 6; +const int ArgumentReg4 = 7; +const int FramePointerReg = 31; +const int StackPointerReg = 1; + +// There isn't one in Power, but we need to define one somewhere +const int ZeroReg = NumIntRegs - 1; + +const int SyscallNumReg = 0; +const int SyscallPseudoReturnReg = 3; +const int SyscallSuccessReg = 3; + +// These help enumerate all the registers for dependence tracking. +const int FP_Base_DepTag = NumIntRegs; +const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs; + +typedef union { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; +} AnyReg; + +enum MiscIntRegNums { + INTREG_CR = NumIntArchRegs, + INTREG_XER, + INTREG_LR, + INTREG_CTR, + INTREG_FPSCR, + INTREG_RSV, + INTREG_RSV_LEN, + INTREG_RSV_ADDR +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_REGISTERS_HH__ diff --git a/src/arch/power/remote_gdb.hh b/src/arch/power/remote_gdb.hh new file mode 100644 index 0000000000..34bb4bd1fc --- /dev/null +++ b/src/arch/power/remote_gdb.hh @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_ARM_REMOTE_GDB_HH__ +#define __ARCH_ARM_REMOTE_GDB_HH__ + +#include "base/remote_gdb.hh" + +namespace PowerISA +{ + +class RemoteGDB : public BaseRemoteGDB +{ + public: + RemoteGDB(System *system, ThreadContext *context) + : BaseRemoteGDB(system, context, 1) + { + } + + bool + acc(Addr, size_t) + { + panic("acc not implemented for POWER!"); + } + + void + getregs() + { + panic("getregs not implemented for POWER!"); + } + + void + setregs() + { + panic("setregs not implemented for POWER!"); + } + + void + clearSingleStep() + { + panic("clearSingleStep not implemented for POWER!"); + } + + void + setSingleStep() + { + panic("setSingleStep not implemented for POWER!"); + } +}; + +} // PowerISA namespace + +#endif /* __ARCH_POWER_REMOTE_GDB_H__ */ diff --git a/src/arch/power/stacktrace.hh b/src/arch/power/stacktrace.hh new file mode 100644 index 0000000000..49d687a6ea --- /dev/null +++ b/src/arch/power/stacktrace.hh @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_STACKTRACE_HH__ +#define __ARCH_POWER_STACKTRACE_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +class ThreadContext; +class StackTrace; + +namespace PowerISA +{ + +class ProcessInfo +{ + private: + ThreadContext *tc; + + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; + + public: + ProcessInfo(ThreadContext *_tc); + + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; +}; + +class StackTrace +{ + protected: + typedef TheISA::MachInst MachInst; + private: + ThreadContext *tc; + std::vector stack; + + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); + + void trace(ThreadContext *tc, bool is_call); + + public: + StackTrace(); + StackTrace(ThreadContext *tc, StaticInstPtr inst); + ~StackTrace(); + + void + clear() + { + tc = 0; + stack.clear(); + } + + bool + valid() const + { + return tc != NULL; + } + + bool trace(ThreadContext *tc, StaticInstPtr inst); + + public: + const std::vector & + getstack() const + { + return stack; + } + + static const int user = 1; + static const int console = 2; + static const int unknown = 3; + +#if TRACING_ON + private: + void dump(); + + public: + void + dprintf() + { + if (DTRACE(Stack)) + dump(); + } +#else + public: + void + dprintf() + { + } +#endif +}; + +inline bool +StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) +{ + if (!inst->isCall() && !inst->isReturn()) + return false; + + if (valid()) + clear(); + + trace(tc, !inst->isReturn()); + return true; +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_STACKTRACE_HH__ diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc new file mode 100644 index 0000000000..125c92a1a8 --- /dev/null +++ b/src/arch/power/tlb.cc @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Jaidev Patwardhan + * Stephen Hines + * Timothy M. Jones + */ + +#include +#include + +#include "arch/power/faults.hh" +#include "arch/power/pagetable.hh" +#include "arch/power/tlb.hh" +#include "arch/power/utility.hh" +#include "base/inifile.hh" +#include "base/str.hh" +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "mem/page_table.hh" +#include "params/PowerTLB.hh" +#include "sim/process.hh" + + +using namespace std; +using namespace PowerISA; + +/////////////////////////////////////////////////////////////////////// +// +// POWER TLB +// + +#define MODE2MASK(X) (1 << (X)) + +TLB::TLB(const Params *p) + : BaseTLB(p), size(p->size), nlu(0) +{ + table = new PowerISA::PTE[size]; + memset(table, 0, sizeof(PowerISA::PTE[size])); + smallPages = 0; +} + +TLB::~TLB() +{ + if (table) + delete [] table; +} + +// look up an entry in the TLB +PowerISA::PTE * +TLB::lookup(Addr vpn, uint8_t asn) const +{ + // assume not found... + PowerISA::PTE *retval = NULL; + PageTable::const_iterator i = lookupTable.find(vpn); + if (i != lookupTable.end()) { + while (i->first == vpn) { + int index = i->second; + PowerISA::PTE *pte = &table[index]; + Addr Mask = pte->Mask; + Addr InvMask = ~Mask; + Addr VPN = pte->VPN; + if (((vpn & InvMask) == (VPN & InvMask)) + && (pte->G || (asn == pte->asid))) { + + // We have a VPN + ASID Match + retval = pte; + break; + } + ++i; + } + } + + DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, + retval ? "hit" : "miss", retval ? retval->PFN1 : 0); + return retval; +} + +PowerISA::PTE* +TLB::getEntry(unsigned Index) const +{ + // Make sure that Index is valid + assert(Indexfirst == vpn) { + int index = i->second; + PowerISA::PTE *pte = &table[index]; + Addr Mask = pte->Mask; + Addr InvMask = ~Mask; + Addr VPN = pte->VPN; + if (((vpn & InvMask) == (VPN & InvMask)) + && (pte->G || (asn == pte->asid))) { + + // We have a VPN + ASID Match + retval = pte; + Ind = index; + break; + } + ++i; + } + } + + DPRINTF(Power, "VPN: %x, asid: %d, Result of TLBP: %d\n", vpn, asn, Ind); + return Ind; +} + +inline Fault +TLB::checkCacheability(RequestPtr &req) +{ + Addr VAddrUncacheable = 0xA0000000; + if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { + + // mark request as uncacheable + req->setFlags(Request::UNCACHEABLE); + } + return NoFault; +} + +void +TLB::insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages) +{ + smallPages=_smallPages; + if (Index > size){ + warn("Attempted to write at index (%d) beyond TLB size (%d)", + Index, size); + } else { + + // Update TLB + if (table[Index].V0 == true || table[Index].V1 == true) { + + // Previous entry is valid + PageTable::iterator i = lookupTable.find(table[Index].VPN); + lookupTable.erase(i); + } + table[Index]=pte; + + // Update fast lookup table + lookupTable.insert(make_pair(table[Index].VPN, Index)); + } +} + +// insert a new TLB entry +void +TLB::insert(Addr addr, PowerISA::PTE &pte) +{ + fatal("TLB Insert not yet implemented\n"); +} + +void +TLB::flushAll() +{ + DPRINTF(TLB, "flushAll\n"); + memset(table, 0, sizeof(PowerISA::PTE[size])); + lookupTable.clear(); + nlu = 0; +} + +void +TLB::serialize(ostream &os) +{ + SERIALIZE_SCALAR(size); + SERIALIZE_SCALAR(nlu); + + for (int i = 0; i < size; i++) { + nameOut(os, csprintf("%s.PTE%d", name(), i)); + table[i].serialize(os); + } +} + +void +TLB::unserialize(Checkpoint *cp, const string §ion) +{ + UNSERIALIZE_SCALAR(size); + UNSERIALIZE_SCALAR(nlu); + + for (int i = 0; i < size; i++) { + table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); + if (table[i].V0 || table[i].V1) { + lookupTable.insert(make_pair(table[i].VPN, i)); + } + } +} + +void +TLB::regStats() +{ + read_hits + .name(name() + ".read_hits") + .desc("DTB read hits") + ; + + read_misses + .name(name() + ".read_misses") + .desc("DTB read misses") + ; + + + read_accesses + .name(name() + ".read_accesses") + .desc("DTB read accesses") + ; + + write_hits + .name(name() + ".write_hits") + .desc("DTB write hits") + ; + + write_misses + .name(name() + ".write_misses") + .desc("DTB write misses") + ; + + + write_accesses + .name(name() + ".write_accesses") + .desc("DTB write accesses") + ; + + hits + .name(name() + ".hits") + .desc("DTB hits") + ; + + misses + .name(name() + ".misses") + .desc("DTB misses") + ; + + invalids + .name(name() + ".invalids") + .desc("DTB access violations") + ; + + accesses + .name(name() + ".accesses") + .desc("DTB accesses") + ; + + hits = read_hits + write_hits; + misses = read_misses + write_misses; + accesses = read_accesses + write_accesses; +} + +Fault +TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) +{ +#if !FULL_SYSTEM + Process * p = tc->getProcessPtr(); + + Fault fault = p->pTable->translate(req); + if (fault != NoFault) + return fault; + + return NoFault; +#else + fatal("translate atomic not yet implemented\n"); +#endif +} + +void +TLB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, Mode mode) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, mode), req, tc, mode); +} + +PowerISA::PTE & +TLB::index(bool advance) +{ + PowerISA::PTE *pte = &table[nlu]; + + if (advance) + nextnlu(); + + return *pte; +} + +PowerISA::TLB * +PowerTLBParams::create() +{ + return new PowerISA::TLB(this); +} diff --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh new file mode 100644 index 0000000000..8b6c7233da --- /dev/null +++ b/src/arch/power/tlb.hh @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_TLB_HH__ +#define __ARCH_POWER_TLB_HH__ + +#include + +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" +#include "arch/power/vtophys.hh" +#include "arch/power/pagetable.hh" +#include "base/statistics.hh" +#include "mem/request.hh" +#include "params/PowerTLB.hh" +#include "sim/faults.hh" +#include "sim/tlb.hh" + +class ThreadContext; + +namespace PowerISA { + +// This is copied from the ARM ISA and has not been checked against the +// Power at all. +struct TlbEntry +{ + Addr _pageStart; + + TlbEntry() + { + } + + TlbEntry(Addr asn, Addr vaddr, Addr paddr) + : _pageStart(paddr) + { + } + + void + updateVaddr(Addr new_vaddr) + { + panic("unimplemented"); + } + + Addr + pageStart() + { + return _pageStart; + } + + void + serialize(std::ostream &os) + { + SERIALIZE_SCALAR(_pageStart); + } + + void + unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_SCALAR(_pageStart); + } +}; + +class TLB : public BaseTLB +{ + protected: + typedef std::multimap PageTable; + PageTable lookupTable; // Quick lookup into page table + + PowerISA::PTE *table; // the Page Table + int size; // TLB Size + int nlu; // not last used entry (for replacement) + + void + nextnlu() + { + if (++nlu >= size) { + nlu = 0; + } + } + + PowerISA::PTE *lookup(Addr vpn, uint8_t asn) const; + + mutable Stats::Scalar read_hits; + mutable Stats::Scalar read_misses; + mutable Stats::Scalar read_acv; + mutable Stats::Scalar read_accesses; + mutable Stats::Scalar write_hits; + mutable Stats::Scalar write_misses; + mutable Stats::Scalar write_acv; + mutable Stats::Scalar write_accesses; + Stats::Formula hits; + Stats::Formula misses; + Stats::Formula invalids; + Stats::Formula accesses; + + public: + typedef PowerTLBParams Params; + TLB(const Params *p); + virtual ~TLB(); + + int probeEntry(Addr vpn,uint8_t) const; + PowerISA::PTE *getEntry(unsigned) const; + + int smallPages; + + int + getsize() const + { + return size; + } + + PowerISA::PTE &index(bool advance = true); + void insert(Addr vaddr, PowerISA::PTE &pte); + void insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages); + void flushAll(); + + void + demapPage(Addr vaddr, uint64_t asn) + { + panic("demapPage unimplemented.\n"); + } + + // static helper functions... really + static bool validVirtualAddress(Addr vaddr); + static Fault checkCacheability(RequestPtr &req); + Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, Mode mode); + + // Checkpointing + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + void regStats(); +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_TLB_HH__ diff --git a/src/arch/power/types.hh b/src/arch/power/types.hh new file mode 100644 index 0000000000..7b994adc91 --- /dev/null +++ b/src/arch/power/types.hh @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_TYPES_HH__ +#define __ARCH_POWER_TYPES_HH__ + +#include "base/bitunion.hh" +#include "base/types.hh" + +namespace PowerISA +{ + +typedef uint32_t MachInst; + +BitUnion32(ExtMachInst) + + // Registers + Bitfield<25, 21> rs; + Bitfield<20, 16> ra; + + // Shifts and masks + Bitfield<15, 11> sh; + Bitfield<10, 6> mb; + Bitfield< 5, 1> me; + + // Immediate fields + Bitfield<15, 0> si; + Bitfield<15, 0> d; + + // Special purpose register identifier + Bitfield<20, 11> spr; + Bitfield<25, 2> li; + Bitfield<1> aa; + Bitfield<25, 23> bf; + Bitfield<15, 2> bd; + Bitfield<25, 21> bo; + Bitfield<20, 16> bi; + Bitfield<20, 18> bfa; + + // Record bits + Bitfield<0> rc31; + Bitfield<10> oe; + + // Condition register fields + Bitfield<25, 21> bt; + Bitfield<20, 16> ba; + Bitfield<15, 11> bb; + + // FXM field for mtcrf instruction + Bitfield<19, 12> fxm; +EndBitUnion(ExtMachInst) + +// typedef uint64_t LargestRead; +// // Need to use 64 bits to make sure that read requests get handled properly + +// typedef int RegContextParam; +// typedef int RegContextVal; + +struct CoreSpecific { +}; + +} // PowerISA namspace + +#endif // __ARCH_POWER_TYPES_HH__ diff --git a/src/arch/power/utility.hh b/src/arch/power/utility.hh new file mode 100644 index 0000000000..442075aa2f --- /dev/null +++ b/src/arch/power/utility.hh @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Korey Sewell + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_UTILITY_HH__ +#define __ARCH_POWER_UTILITY_HH__ + +#include "arch/power/miscregs.hh" +#include "arch/power/types.hh" +#include "base/hashmap.hh" +#include "base/types.hh" +#include "cpu/thread_context.hh" + +namespace __hash_namespace { + +template<> +struct hash : public hash { + size_t operator()(const PowerISA::ExtMachInst &emi) const { + return hash::operator()((uint32_t)emi); + }; +}; + +} // __hash_namespace namespace + +namespace PowerISA { + +/** + * Function to ensure ISA semantics about 0 registers. + * @param tc The thread context. + */ +template +void zeroRegisters(TC *tc); + +// Instruction address compression hooks +static inline Addr +realPCToFetchPC(const Addr &addr) +{ + return addr; +} + +static inline Addr +fetchPCToRealPC(const Addr &addr) +{ + return addr; +} + +// the size of "fetched" instructions +static inline size_t +fetchInstSize() +{ + return sizeof(MachInst); +} + +static inline MachInst +makeRegisterCopy(int dest, int src) +{ + panic("makeRegisterCopy not implemented"); + return 0; +} + +inline void +startupCPU(ThreadContext *tc, int cpuId) +{ + tc->activate(0); +} + +template +Fault +checkFpEnableFault(XC *xc) +{ + return NoFault; +} + +static inline void +copyRegs(ThreadContext *src, ThreadContext *dest) +{ + panic("Copy Regs Not Implemented Yet\n"); +} + +static inline void +copyMiscRegs(ThreadContext *src, ThreadContext *dest) +{ + panic("Copy Misc. Regs Not Implemented Yet\n"); +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_UTILITY_HH__ diff --git a/src/arch/power/vtophys.hh b/src/arch/power/vtophys.hh new file mode 100644 index 0000000000..3cfebcfc75 --- /dev/null +++ b/src/arch/power/vtophys.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Nathan Binkert + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_VTOPHYS_HH__ +#define __ARCH_POWER_VTOPHYS_HH__ + +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" + + +class ThreadContext; +class FunctionalPort; + +namespace PowerISA { + +inline Addr +PteAddr(Addr a) +{ + return (a & PteMask) << PteShift; +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_VTOPHYS_HH__ + diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 15ad88f762..60f0f99b49 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -97,6 +97,19 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) arch = ObjectFile::Alpha; } else if (ehdr.e_machine == EM_ARM) { arch = ObjectFile::Arm; + } else if (ehdr.e_machine == EM_PPC && + ehdr.e_ident[EI_CLASS] == ELFCLASS32) { + if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) { + arch = ObjectFile::Power; + } else { + fatal("The binary you're trying to load is compiled for " + "little endian Power.\nM5 only supports big " + "endian Power. Please recompile your binary.\n"); + } + } else if (ehdr.e_machine == EM_PPC64) { + fatal("The binary you're trying to load is compiled for 64-bit " + "Power. M5\n only supports 32-bit Power. Please " + "recompile your binary.\n"); } else { warn("Unknown architecture: %d\n", ehdr.e_machine); arch = ObjectFile::UnknownArch; diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh index e511451b79..b08f1c633b 100644 --- a/src/base/loader/object_file.hh +++ b/src/base/loader/object_file.hh @@ -52,7 +52,8 @@ class ObjectFile Mips, X86_64, I386, - Arm + Arm, + Power }; enum OpSys { diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 75114053e7..ac734e5ac4 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -59,6 +59,10 @@ elif buildEnv['TARGET_ISA'] == 'arm': from ArmTLB import ArmTLB if buildEnv['FULL_SYSTEM']: from ArmInterrupts import ArmInterrupts +elif buildEnv['TARGET_ISA'] == 'power': + from PowerTLB import PowerTLB + if buildEnv['FULL_SYSTEM']: + from PowerInterrupts import PowerInterrupts class BaseCPU(MemObject): type = 'BaseCPU' @@ -116,6 +120,13 @@ class BaseCPU(MemObject): if buildEnv['FULL_SYSTEM']: interrupts = Param.ArmInterrupts( ArmInterrupts(), "Interrupt Controller") + elif buildEnv['TARGET_ISA'] == 'power': + UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?") + dtb = Param.PowerTLB(PowerTLB(), "Data TLB") + itb = Param.PowerTLB(PowerTLB(), "Instruction TLB") + if buildEnv['FULL_SYSTEM']: + interrupts = Param.PowerInterrupts( + PowerInterrupts(), "Interrupt Controller") else: print "Don't know what TLB to use for ISA %s" % \ buildEnv['TARGET_ISA'] diff --git a/src/sim/process.cc b/src/sim/process.cc index ec6ac04492..cf0f2b84d2 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -66,6 +66,8 @@ #include "arch/arm/linux/process.hh" #elif THE_ISA == X86_ISA #include "arch/x86/linux/process.hh" +#elif THE_ISA == POWER_ISA +#include "arch/power/linux/process.hh" #else #error "THE_ISA not set" #endif @@ -626,7 +628,7 @@ LiveProcess::argsInit(int intSize, int pageSize) tc->setPC(prog_entry); tc->setNextPC(prog_entry + sizeof(MachInst)); -#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc +#if THE_ISA != ALPHA_ISA && THE_ISA != POWER_ISA //e.g. MIPS or Sparc tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); #endif @@ -754,6 +756,20 @@ LiveProcess::create(LiveProcessParams * params) default: fatal("Unknown/unsupported operating system."); } +#elif THE_ISA == POWER_ISA + if (objFile->getArch() != ObjectFile::Power) + fatal("Object file architecture does not match compiled ISA (Power)."); + switch (objFile->getOpSys()) { + case ObjectFile::UnknownOpSys: + warn("Unknown operating system; assuming Linux."); + // fall through + case ObjectFile::Linux: + process = new PowerLinuxProcess(params, objFile); + break; + + default: + fatal("Unknown/unsupported operating system."); + } #else #error "THE_ISA not set" #endif From 2b232e11a8395c90e792fe743fc681bb3abfb16f Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Tue, 27 Oct 2009 09:24:40 -0700 Subject: [PATCH 056/160] test: Hello world test program for Power includes reference outputs for the Hello World tests on simple-atomic and o3-timing. --- .../ref/power/linux/o3-timing/config.ini | 389 ++++++++++++++++ .../00.hello/ref/power/linux/o3-timing/simerr | 5 + .../00.hello/ref/power/linux/o3-timing/simout | 16 + .../ref/power/linux/o3-timing/stats.txt | 421 ++++++++++++++++++ .../ref/power/linux/simple-atomic/config.ini | 91 ++++ .../ref/power/linux/simple-atomic/simerr | 5 + .../ref/power/linux/simple-atomic/simout | 16 + .../ref/power/linux/simple-atomic/stats.txt | 36 ++ tests/test-progs/hello/bin/power/linux/hello | Bin 0 -> 625955 bytes 9 files changed, 979 insertions(+) create mode 100644 tests/quick/00.hello/ref/power/linux/o3-timing/config.ini create mode 100755 tests/quick/00.hello/ref/power/linux/o3-timing/simerr create mode 100755 tests/quick/00.hello/ref/power/linux/o3-timing/simout create mode 100644 tests/quick/00.hello/ref/power/linux/o3-timing/stats.txt create mode 100644 tests/quick/00.hello/ref/power/linux/simple-atomic/config.ini create mode 100755 tests/quick/00.hello/ref/power/linux/simple-atomic/simerr create mode 100755 tests/quick/00.hello/ref/power/linux/simple-atomic/simout create mode 100644 tests/quick/00.hello/ref/power/linux/simple-atomic/stats.txt create mode 100755 tests/test-progs/hello/bin/power/linux/hello diff --git a/tests/quick/00.hello/ref/power/linux/o3-timing/config.ini b/tests/quick/00.hello/ref/power/linux/o3-timing/config.ini new file mode 100644 index 0000000000..6b0ea33cd3 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/o3-timing/config.ini @@ -0,0 +1,389 @@ +[root] +type=Root +children=system +dummy=0 + +[system] +type=System +children=cpu membus physmem +mem_mode=atomic +physmem=system.physmem + +[system.cpu] +type=DerivO3CPU +children=dcache dtb fuPool icache itb l2cache toL2Bus tracer workload +BTBEntries=4096 +BTBTagSize=16 +LFSTSize=1024 +LQEntries=32 +RASSize=16 +SQEntries=32 +SSITSize=1024 +UnifiedTLB=true +activity=0 +backComSize=5 +cachePorts=200 +checker=Null +choiceCtrBits=2 +choicePredictorSize=8192 +clock=500 +commitToDecodeDelay=1 +commitToFetchDelay=1 +commitToIEWDelay=1 +commitToRenameDelay=1 +commitWidth=8 +cpu_id=0 +decodeToFetchDelay=1 +decodeToRenameDelay=1 +decodeWidth=8 +defer_registration=false +dispatchWidth=8 +do_checkpoint_insts=true +do_statistics_insts=true +dtb=system.cpu.dtb +fetchToDecodeDelay=1 +fetchTrapLatency=1 +fetchWidth=8 +forwardComSize=5 +fuPool=system.cpu.fuPool +function_trace=false +function_trace_start=0 +globalCtrBits=2 +globalHistoryBits=13 +globalPredictorSize=8192 +iewToCommitDelay=1 +iewToDecodeDelay=1 +iewToFetchDelay=1 +iewToRenameDelay=1 +instShiftAmt=2 +issueToExecuteDelay=1 +issueWidth=8 +itb=system.cpu.itb +localCtrBits=2 +localHistoryBits=11 +localHistoryTableSize=2048 +localPredictorSize=2048 +max_insts_all_threads=0 +max_insts_any_thread=0 +max_loads_all_threads=0 +max_loads_any_thread=0 +numIQEntries=64 +numPhysFloatRegs=256 +numPhysIntRegs=256 +numROBEntries=192 +numRobs=1 +numThreads=1 +phase=0 +predType=tournament +progress_interval=0 +renameToDecodeDelay=1 +renameToFetchDelay=1 +renameToIEWDelay=2 +renameToROBDelay=1 +renameWidth=8 +smtCommitPolicy=RoundRobin +smtFetchPolicy=SingleThread +smtIQPolicy=Partitioned +smtIQThreshold=100 +smtLSQPolicy=Partitioned +smtLSQThreshold=100 +smtNumFetchingThreads=1 +smtROBPolicy=Partitioned +smtROBThreshold=100 +squashWidth=8 +system=system +tracer=system.cpu.tracer +trapLatency=13 +wbDepth=1 +wbWidth=8 +workload=system.cpu.workload +dcache_port=system.cpu.dcache.cpu_side +icache_port=system.cpu.icache.cpu_side + +[system.cpu.dcache] +type=BaseCache +addr_range=0:18446744073709551615 +assoc=2 +block_size=64 +forward_snoops=true +hash_delay=1 +latency=1000 +max_miss_count=0 +mshrs=10 +prefetch_data_accesses_only=false +prefetch_degree=1 +prefetch_latency=10000 +prefetch_on_access=false +prefetch_past_page=false +prefetch_policy=none +prefetch_serial_squash=false +prefetch_use_cpu_id=true +prefetcher_size=100 +prioritizeRequests=false +repl=Null +size=262144 +subblock_size=0 +tgts_per_mshr=20 +trace_addr=0 +two_queue=false +write_buffers=8 +cpu_side=system.cpu.dcache_port +mem_side=system.cpu.toL2Bus.port[1] + +[system.cpu.dtb] +type=PowerTLB +size=64 + +[system.cpu.fuPool] +type=FUPool +children=FUList0 FUList1 FUList2 FUList3 FUList4 FUList5 FUList6 FUList7 +FUList=system.cpu.fuPool.FUList0 system.cpu.fuPool.FUList1 system.cpu.fuPool.FUList2 system.cpu.fuPool.FUList3 system.cpu.fuPool.FUList4 system.cpu.fuPool.FUList5 system.cpu.fuPool.FUList6 system.cpu.fuPool.FUList7 + +[system.cpu.fuPool.FUList0] +type=FUDesc +children=opList +count=6 +opList=system.cpu.fuPool.FUList0.opList + +[system.cpu.fuPool.FUList0.opList] +type=OpDesc +issueLat=1 +opClass=IntAlu +opLat=1 + +[system.cpu.fuPool.FUList1] +type=FUDesc +children=opList0 opList1 +count=2 +opList=system.cpu.fuPool.FUList1.opList0 system.cpu.fuPool.FUList1.opList1 + +[system.cpu.fuPool.FUList1.opList0] +type=OpDesc +issueLat=1 +opClass=IntMult +opLat=3 + +[system.cpu.fuPool.FUList1.opList1] +type=OpDesc +issueLat=19 +opClass=IntDiv +opLat=20 + +[system.cpu.fuPool.FUList2] +type=FUDesc +children=opList0 opList1 opList2 +count=4 +opList=system.cpu.fuPool.FUList2.opList0 system.cpu.fuPool.FUList2.opList1 system.cpu.fuPool.FUList2.opList2 + +[system.cpu.fuPool.FUList2.opList0] +type=OpDesc +issueLat=1 +opClass=FloatAdd +opLat=2 + +[system.cpu.fuPool.FUList2.opList1] +type=OpDesc +issueLat=1 +opClass=FloatCmp +opLat=2 + +[system.cpu.fuPool.FUList2.opList2] +type=OpDesc +issueLat=1 +opClass=FloatCvt +opLat=2 + +[system.cpu.fuPool.FUList3] +type=FUDesc +children=opList0 opList1 opList2 +count=2 +opList=system.cpu.fuPool.FUList3.opList0 system.cpu.fuPool.FUList3.opList1 system.cpu.fuPool.FUList3.opList2 + +[system.cpu.fuPool.FUList3.opList0] +type=OpDesc +issueLat=1 +opClass=FloatMult +opLat=4 + +[system.cpu.fuPool.FUList3.opList1] +type=OpDesc +issueLat=12 +opClass=FloatDiv +opLat=12 + +[system.cpu.fuPool.FUList3.opList2] +type=OpDesc +issueLat=24 +opClass=FloatSqrt +opLat=24 + +[system.cpu.fuPool.FUList4] +type=FUDesc +children=opList +count=0 +opList=system.cpu.fuPool.FUList4.opList + +[system.cpu.fuPool.FUList4.opList] +type=OpDesc +issueLat=1 +opClass=MemRead +opLat=1 + +[system.cpu.fuPool.FUList5] +type=FUDesc +children=opList +count=0 +opList=system.cpu.fuPool.FUList5.opList + +[system.cpu.fuPool.FUList5.opList] +type=OpDesc +issueLat=1 +opClass=MemWrite +opLat=1 + +[system.cpu.fuPool.FUList6] +type=FUDesc +children=opList0 opList1 +count=4 +opList=system.cpu.fuPool.FUList6.opList0 system.cpu.fuPool.FUList6.opList1 + +[system.cpu.fuPool.FUList6.opList0] +type=OpDesc +issueLat=1 +opClass=MemRead +opLat=1 + +[system.cpu.fuPool.FUList6.opList1] +type=OpDesc +issueLat=1 +opClass=MemWrite +opLat=1 + +[system.cpu.fuPool.FUList7] +type=FUDesc +children=opList +count=1 +opList=system.cpu.fuPool.FUList7.opList + +[system.cpu.fuPool.FUList7.opList] +type=OpDesc +issueLat=3 +opClass=IprAccess +opLat=3 + +[system.cpu.icache] +type=BaseCache +addr_range=0:18446744073709551615 +assoc=2 +block_size=64 +forward_snoops=true +hash_delay=1 +latency=1000 +max_miss_count=0 +mshrs=10 +prefetch_data_accesses_only=false +prefetch_degree=1 +prefetch_latency=10000 +prefetch_on_access=false +prefetch_past_page=false +prefetch_policy=none +prefetch_serial_squash=false +prefetch_use_cpu_id=true +prefetcher_size=100 +prioritizeRequests=false +repl=Null +size=131072 +subblock_size=0 +tgts_per_mshr=20 +trace_addr=0 +two_queue=false +write_buffers=8 +cpu_side=system.cpu.icache_port +mem_side=system.cpu.toL2Bus.port[0] + +[system.cpu.itb] +type=PowerTLB +size=64 + +[system.cpu.l2cache] +type=BaseCache +addr_range=0:18446744073709551615 +assoc=2 +block_size=64 +forward_snoops=true +hash_delay=1 +latency=1000 +max_miss_count=0 +mshrs=10 +prefetch_data_accesses_only=false +prefetch_degree=1 +prefetch_latency=10000 +prefetch_on_access=false +prefetch_past_page=false +prefetch_policy=none +prefetch_serial_squash=false +prefetch_use_cpu_id=true +prefetcher_size=100 +prioritizeRequests=false +repl=Null +size=2097152 +subblock_size=0 +tgts_per_mshr=5 +trace_addr=0 +two_queue=false +write_buffers=8 +cpu_side=system.cpu.toL2Bus.port[2] +mem_side=system.membus.port[1] + +[system.cpu.toL2Bus] +type=Bus +block_size=64 +bus_id=0 +clock=1000 +header_cycles=1 +responder_set=false +width=64 +port=system.cpu.icache.mem_side system.cpu.dcache.mem_side system.cpu.l2cache.cpu_side + +[system.cpu.tracer] +type=ExeTracer + +[system.cpu.workload] +type=LiveProcess +cmd=hello +cwd= +egid=100 +env= +errout=cerr +euid=100 +executable=tests/test-progs/hello/bin/power/linux/hello +gid=100 +input=cin +max_stack_size=67108864 +output=cout +pid=100 +ppid=99 +simpoint=0 +system=system +uid=100 + +[system.membus] +type=Bus +block_size=64 +bus_id=0 +clock=1000 +header_cycles=1 +responder_set=false +width=64 +port=system.physmem.port[0] system.cpu.l2cache.mem_side + +[system.physmem] +type=PhysicalMemory +file= +latency=30000 +latency_var=0 +null=false +range=0:134217727 +zero=false +port=system.membus.port[0] + diff --git a/tests/quick/00.hello/ref/power/linux/o3-timing/simerr b/tests/quick/00.hello/ref/power/linux/o3-timing/simerr new file mode 100755 index 0000000000..a2692a6c90 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/o3-timing/simerr @@ -0,0 +1,5 @@ +warn: Sockets disabled, not accepting gdb connections +For more information see: http://www.m5sim.org/warn/d946bea6 +warn: allowing mmap of file @ fd 4294967295. This will break if not /dev/zero. +For more information see: http://www.m5sim.org/warn/3a2134f6 +hack: be nice to actually delete the event here diff --git a/tests/quick/00.hello/ref/power/linux/o3-timing/simout b/tests/quick/00.hello/ref/power/linux/o3-timing/simout new file mode 100755 index 0000000000..bc2c673ec3 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/o3-timing/simout @@ -0,0 +1,16 @@ +M5 Simulator System + +Copyright (c) 2001-2008 +The Regents of The University of Michigan +All Rights Reserved + + +M5 compiled Oct 15 2009 15:43:13 +M5 revision b43c2c69a460 6694 default hello-world-outputs.patch qtip tip +M5 started Oct 15 2009 15:49:09 +M5 executing on frontend01 +command line: build/POWER_SE/m5.fast -d build/POWER_SE/tests/fast/quick/00.hello/power/linux/o3-timing -re tests/run.py build/POWER_SE/tests/fast/quick/00.hello/power/linux/o3-timing +Global frequency set at 1000000000000 ticks per second +info: Entering event queue @ 0. Starting simulation... +Hello world! +Exiting @ tick 11960500 because target called exit() diff --git a/tests/quick/00.hello/ref/power/linux/o3-timing/stats.txt b/tests/quick/00.hello/ref/power/linux/o3-timing/stats.txt new file mode 100644 index 0000000000..59c9aa3349 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/o3-timing/stats.txt @@ -0,0 +1,421 @@ + +---------- Begin Simulation Statistics ---------- +host_inst_rate 103409 # Simulator instruction rate (inst/s) +host_mem_usage 271924 # Number of bytes of host memory used +host_seconds 0.06 # Real time elapsed on the host +host_tick_rate 212174700 # Simulator tick rate (ticks/s) +sim_freq 1000000000000 # Frequency of simulated ticks +sim_insts 5800 # Number of instructions simulated +sim_seconds 0.000012 # Number of seconds simulated +sim_ticks 11960500 # Number of ticks simulated +system.cpu.BPredUnit.BTBCorrect 0 # Number of correct BTB predictions (this stat may not work properly. +system.cpu.BPredUnit.BTBHits 734 # Number of BTB hits +system.cpu.BPredUnit.BTBLookups 1942 # Number of BTB lookups +system.cpu.BPredUnit.RASInCorrect 31 # Number of incorrect RAS predictions. +system.cpu.BPredUnit.condIncorrect 389 # Number of conditional branches incorrect +system.cpu.BPredUnit.condPredicted 1971 # Number of conditional branches predicted +system.cpu.BPredUnit.lookups 2303 # Number of BP lookups +system.cpu.BPredUnit.usedRAS 188 # Number of times the RAS was used to get a target. +system.cpu.commit.COM:branches 1038 # Number of branches committed +system.cpu.commit.COM:bw_lim_events 51 # number cycles where commit BW limit reached +system.cpu.commit.COM:bw_limited 0 # number of insts not committed due to BW limits +system.cpu.commit.COM:committed_per_cycle::samples 10831 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::mean 0.535500 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::stdev 1.248160 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::underflows 0 0.00% 0.00% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::0-1 8265 76.31% 76.31% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::1-2 1142 10.54% 86.85% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::2-3 659 6.08% 92.94% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::3-4 268 2.47% 95.41% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::4-5 226 2.09% 97.50% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::5-6 118 1.09% 98.59% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::6-7 80 0.74% 99.33% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::7-8 22 0.20% 99.53% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::8 51 0.47% 100.00% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::overflows 0 0.00% 100.00% # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::min_value 0 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::max_value 8 # Number of insts commited each cycle +system.cpu.commit.COM:committed_per_cycle::total 10831 # Number of insts commited each cycle +system.cpu.commit.COM:count 5800 # Number of instructions committed +system.cpu.commit.COM:loads 962 # Number of loads committed +system.cpu.commit.COM:membars 7 # Number of memory barriers committed +system.cpu.commit.COM:refs 2008 # Number of memory references committed +system.cpu.commit.COM:swp_count 0 # Number of s/w prefetches committed +system.cpu.commit.branchMispredicts 243 # The number of times a branch was mispredicted +system.cpu.commit.commitCommittedInsts 5800 # The number of committed instructions +system.cpu.commit.commitNonSpecStalls 16 # The number of times commit has been forced to stall to communicate backwards +system.cpu.commit.commitSquashedInsts 3801 # The number of squashed insts skipped by commit +system.cpu.committedInsts 5800 # Number of Instructions Simulated +system.cpu.committedInsts_total 5800 # Number of Instructions Simulated +system.cpu.cpi 4.124483 # CPI: Cycles Per Instruction +system.cpu.cpi_total 4.124483 # CPI: Total CPI of All Threads +system.cpu.dcache.ReadReq_accesses 1436 # number of ReadReq accesses(hits+misses) +system.cpu.dcache.ReadReq_avg_miss_latency 33320.224719 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 34437.500000 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 1347 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 2965500 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.061978 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 89 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_hits 33 # number of ReadReq MSHR hits +system.cpu.dcache.ReadReq_mshr_miss_latency 1928500 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.038997 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 56 # number of ReadReq MSHR misses +system.cpu.dcache.WriteReq_accesses 1046 # number of WriteReq accesses(hits+misses) +system.cpu.dcache.WriteReq_avg_miss_latency 33497.150997 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 35861.538462 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 695 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 11757500 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.335564 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 351 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_hits 286 # number of WriteReq MSHR hits +system.cpu.dcache.WriteReq_mshr_miss_latency 2331000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.062141 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 65 # number of WriteReq MSHR misses +system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked +system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked +system.cpu.dcache.avg_refs 20.048077 # Average number of references to valid blocks. +system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked +system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked +system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked +system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked +system.cpu.dcache.cache_copies 0 # number of cache copies performed +system.cpu.dcache.demand_accesses 2482 # number of demand (read+write) accesses +system.cpu.dcache.demand_avg_miss_latency 33461.363636 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 35202.479339 # average overall mshr miss latency +system.cpu.dcache.demand_hits 2042 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 14723000 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.177276 # miss rate for demand accesses +system.cpu.dcache.demand_misses 440 # number of demand (read+write) misses +system.cpu.dcache.demand_mshr_hits 319 # number of demand (read+write) MSHR hits +system.cpu.dcache.demand_mshr_miss_latency 4259500 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.048751 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 121 # number of demand (read+write) MSHR misses +system.cpu.dcache.fast_writes 0 # number of fast writes performed +system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated +system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate +system.cpu.dcache.overall_accesses 2482 # number of overall (read+write) accesses +system.cpu.dcache.overall_avg_miss_latency 33461.363636 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 35202.479339 # average overall mshr miss latency +system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency +system.cpu.dcache.overall_hits 2042 # number of overall hits +system.cpu.dcache.overall_miss_latency 14723000 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.177276 # miss rate for overall accesses +system.cpu.dcache.overall_misses 440 # number of overall misses +system.cpu.dcache.overall_mshr_hits 319 # number of overall MSHR hits +system.cpu.dcache.overall_mshr_miss_latency 4259500 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.048751 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 121 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles +system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses +system.cpu.dcache.replacements 0 # number of replacements +system.cpu.dcache.sampled_refs 104 # Sample count of references to valid blocks. +system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions +system.cpu.dcache.tagsinuse 66.056188 # Cycle average of tags in use +system.cpu.dcache.total_refs 2085 # Total number of references to valid blocks. +system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. +system.cpu.dcache.writebacks 0 # number of writebacks +system.cpu.decode.DECODE:BlockedCycles 1201 # Number of cycles decode is blocked +system.cpu.decode.DECODE:BranchMispred 148 # Number of times decode detected a branch misprediction +system.cpu.decode.DECODE:BranchResolved 256 # Number of times decode resolved a branch +system.cpu.decode.DECODE:DecodedInsts 10901 # Number of instructions handled by decode +system.cpu.decode.DECODE:IdleCycles 7556 # Number of cycles decode is idle +system.cpu.decode.DECODE:RunCycles 2000 # Number of cycles decode is running +system.cpu.decode.DECODE:SquashCycles 615 # Number of cycles decode is squashing +system.cpu.decode.DECODE:SquashedInsts 416 # Number of squashed instructions handled by decode +system.cpu.decode.DECODE:UnblockCycles 74 # Number of cycles decode is unblocking +system.cpu.dtb.accesses 0 # DTB accesses +system.cpu.dtb.hits 0 # DTB hits +system.cpu.dtb.misses 0 # DTB misses +system.cpu.dtb.read_accesses 0 # DTB read accesses +system.cpu.dtb.read_hits 0 # DTB read hits +system.cpu.dtb.read_misses 0 # DTB read misses +system.cpu.dtb.write_accesses 0 # DTB write accesses +system.cpu.dtb.write_hits 0 # DTB write hits +system.cpu.dtb.write_misses 0 # DTB write misses +system.cpu.fetch.Branches 2303 # Number of branches that fetch encountered +system.cpu.fetch.CacheLines 1463 # Number of cache lines fetched +system.cpu.fetch.Cycles 3604 # Number of cycles fetch has run and was not squashing or blocked +system.cpu.fetch.IcacheSquashes 216 # Number of outstanding Icache misses that were squashed +system.cpu.fetch.Insts 12241 # Number of instructions fetch has processed +system.cpu.fetch.SquashCycles 411 # Number of cycles fetch has spent squashing +system.cpu.fetch.branchRate 0.096271 # Number of branch fetches per cycle +system.cpu.fetch.icacheStallCycles 1463 # Number of cycles fetch is stalled on an Icache miss +system.cpu.fetch.predictedBranches 922 # Number of branches that fetch has predicted taken +system.cpu.fetch.rate 0.511705 # Number of inst fetches per cycle +system.cpu.fetch.rateDist::samples 11446 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::mean 1.069457 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::stdev 2.458316 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::underflows 0 0.00% 0.00% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::0-1 9306 81.30% 81.30% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::1-2 148 1.29% 82.60% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::2-3 183 1.60% 84.20% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::3-4 143 1.25% 85.44% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::4-5 197 1.72% 87.17% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::5-6 135 1.18% 88.35% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::6-7 371 3.24% 91.59% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::7-8 95 0.83% 92.42% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::8 868 7.58% 100.00% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::overflows 0 0.00% 100.00% # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::min_value 0 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::max_value 8 # Number of instructions fetched each cycle (Total) +system.cpu.fetch.rateDist::total 11446 # Number of instructions fetched each cycle (Total) +system.cpu.icache.ReadReq_accesses 1463 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 36616.094987 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 34771.212121 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_hits 1084 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 13877500 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.259057 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 379 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_hits 49 # number of ReadReq MSHR hits +system.cpu.icache.ReadReq_mshr_miss_latency 11474500 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_rate 0.225564 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_misses 330 # number of ReadReq MSHR misses +system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked +system.cpu.icache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked +system.cpu.icache.avg_refs 3.284848 # Average number of references to valid blocks. +system.cpu.icache.blocked::no_mshrs 0 # number of cycles access was blocked +system.cpu.icache.blocked::no_targets 0 # number of cycles access was blocked +system.cpu.icache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked +system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked +system.cpu.icache.cache_copies 0 # number of cache copies performed +system.cpu.icache.demand_accesses 1463 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 36616.094987 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 34771.212121 # average overall mshr miss latency +system.cpu.icache.demand_hits 1084 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 13877500 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.259057 # miss rate for demand accesses +system.cpu.icache.demand_misses 379 # number of demand (read+write) misses +system.cpu.icache.demand_mshr_hits 49 # number of demand (read+write) MSHR hits +system.cpu.icache.demand_mshr_miss_latency 11474500 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_rate 0.225564 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_misses 330 # number of demand (read+write) MSHR misses +system.cpu.icache.fast_writes 0 # number of fast writes performed +system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated +system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate +system.cpu.icache.overall_accesses 1463 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 36616.094987 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 34771.212121 # average overall mshr miss latency +system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency +system.cpu.icache.overall_hits 1084 # number of overall hits +system.cpu.icache.overall_miss_latency 13877500 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.259057 # miss rate for overall accesses +system.cpu.icache.overall_misses 379 # number of overall misses +system.cpu.icache.overall_mshr_hits 49 # number of overall MSHR hits +system.cpu.icache.overall_mshr_miss_latency 11474500 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_rate 0.225564 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_misses 330 # number of overall MSHR misses +system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles +system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses +system.cpu.icache.replacements 0 # number of replacements +system.cpu.icache.sampled_refs 330 # Sample count of references to valid blocks. +system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions +system.cpu.icache.tagsinuse 159.198376 # Cycle average of tags in use +system.cpu.icache.total_refs 1084 # Total number of references to valid blocks. +system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. +system.cpu.icache.writebacks 0 # number of writebacks +system.cpu.idleCycles 12476 # Total number of cycles that the CPU has spent unscheduled due to idling +system.cpu.iew.EXEC:branches 1260 # Number of branches executed +system.cpu.iew.EXEC:nop 0 # number of nop insts executed +system.cpu.iew.EXEC:rate 0.324680 # Inst execution rate +system.cpu.iew.EXEC:refs 2768 # number of memory reference insts executed +system.cpu.iew.EXEC:stores 1280 # Number of stores executed +system.cpu.iew.EXEC:swp 0 # number of swp insts executed +system.cpu.iew.WB:consumers 5977 # num instructions consuming a value +system.cpu.iew.WB:count 7563 # cumulative count of insts written-back +system.cpu.iew.WB:fanout 0.643801 # average fanout of values written-back +system.cpu.iew.WB:penalized 0 # number of instrctions required to write to 'other' IQ +system.cpu.iew.WB:penalized_rate 0 # fraction of instructions written-back that wrote to 'other' IQ +system.cpu.iew.WB:producers 3848 # num instructions producing a value +system.cpu.iew.WB:rate 0.316152 # insts written-back per cycle +system.cpu.iew.WB:sent 7622 # cumulative count of insts sent to commit +system.cpu.iew.branchMispredicts 279 # Number of branch mispredicts detected at execute +system.cpu.iew.iewBlockCycles 141 # Number of cycles IEW is blocking +system.cpu.iew.iewDispLoadInsts 1815 # Number of dispatched load instructions +system.cpu.iew.iewDispNonSpecInsts 14 # Number of dispatched non-speculative instructions +system.cpu.iew.iewDispSquashedInsts 102 # Number of squashed instructions skipped by dispatch +system.cpu.iew.iewDispStoreInsts 1394 # Number of dispatched store instructions +system.cpu.iew.iewDispatchedInsts 9586 # Number of instructions dispatched to IQ +system.cpu.iew.iewExecLoadInsts 1488 # Number of load instructions executed +system.cpu.iew.iewExecSquashedInsts 320 # Number of squashed instructions skipped in execute +system.cpu.iew.iewExecutedInsts 7767 # Number of executed instructions +system.cpu.iew.iewIQFullEvents 14 # Number of times the IQ has become full, causing a stall +system.cpu.iew.iewIdleCycles 0 # Number of cycles IEW is idle +system.cpu.iew.iewLSQFullEvents 0 # Number of times the LSQ has become full, causing a stall +system.cpu.iew.iewSquashCycles 615 # Number of cycles IEW is squashing +system.cpu.iew.iewUnblockCycles 20 # Number of cycles IEW is unblocking +system.cpu.iew.lsq.thread.0.blockedLoads 0 # Number of blocked loads due to partial load-store forwarding +system.cpu.iew.lsq.thread.0.cacheBlocked 0 # Number of times an access to memory failed due to the cache being blocked +system.cpu.iew.lsq.thread.0.forwLoads 28 # Number of loads that had data forwarded from stores +system.cpu.iew.lsq.thread.0.ignoredResponses 2 # Number of memory responses ignored because the instruction is squashed +system.cpu.iew.lsq.thread.0.invAddrLoads 0 # Number of loads ignored due to an invalid address +system.cpu.iew.lsq.thread.0.invAddrSwpfs 0 # Number of software prefetches ignored due to an invalid address +system.cpu.iew.lsq.thread.0.memOrderViolation 40 # Number of memory ordering violations +system.cpu.iew.lsq.thread.0.rescheduledLoads 1 # Number of loads that were rescheduled +system.cpu.iew.lsq.thread.0.squashedLoads 853 # Number of loads squashed +system.cpu.iew.lsq.thread.0.squashedStores 348 # Number of stores squashed +system.cpu.iew.memOrderViolationEvents 40 # Number of memory order violations +system.cpu.iew.predictedNotTakenIncorrect 215 # Number of branches that were predicted not taken incorrectly +system.cpu.iew.predictedTakenIncorrect 64 # Number of branches that were predicted taken incorrectly +system.cpu.ipc 0.242455 # IPC: Instructions Per Cycle +system.cpu.ipc_total 0.242455 # IPC: Total IPC of All Threads +system.cpu.iq.ISSUE:FU_type_0::No_OpClass 0 0.00% 0.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntAlu 5153 63.72% 63.72% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntMult 0 0.00% 63.72% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IntDiv 0 0.00% 63.72% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatAdd 2 0.02% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatCmp 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatCvt 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatMult 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatDiv 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::FloatSqrt 0 0.00% 63.74% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::MemRead 1611 19.92% 83.67% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::MemWrite 1321 16.33% 100.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::IprAccess 0 0.00% 100.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::InstPrefetch 0 0.00% 100.00% # Type of FU issued +system.cpu.iq.ISSUE:FU_type_0::total 8087 # Type of FU issued +system.cpu.iq.ISSUE:fu_busy_cnt 141 # FU busy when requested +system.cpu.iq.ISSUE:fu_busy_rate 0.017435 # FU busy rate (busy events/executed inst) +system.cpu.iq.ISSUE:fu_full::No_OpClass 0 0.00% 0.00% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::IntAlu 11 7.80% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::IntMult 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::IntDiv 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatAdd 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatCmp 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatCvt 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatMult 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatDiv 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::FloatSqrt 0 0.00% 7.80% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::MemRead 67 47.52% 55.32% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::MemWrite 63 44.68% 100.00% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::IprAccess 0 0.00% 100.00% # attempts to use FU when none available +system.cpu.iq.ISSUE:fu_full::InstPrefetch 0 0.00% 100.00% # attempts to use FU when none available +system.cpu.iq.ISSUE:issued_per_cycle::samples 11446 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::mean 0.706535 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::stdev 1.384911 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::underflows 0 0.00% 0.00% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::0-1 8157 71.27% 71.27% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::1-2 1172 10.24% 81.50% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::2-3 822 7.18% 88.69% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::3-4 530 4.63% 93.32% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::4-5 377 3.29% 96.61% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::5-6 216 1.89% 98.50% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::6-7 120 1.05% 99.55% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::7-8 43 0.38% 99.92% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::8 9 0.08% 100.00% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::overflows 0 0.00% 100.00% # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::min_value 0 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::max_value 8 # Number of insts issued each cycle +system.cpu.iq.ISSUE:issued_per_cycle::total 11446 # Number of insts issued each cycle +system.cpu.iq.ISSUE:rate 0.338057 # Inst issue rate +system.cpu.iq.iqInstsAdded 9564 # Number of instructions added to the IQ (excludes non-spec) +system.cpu.iq.iqInstsIssued 8087 # Number of instructions issued +system.cpu.iq.iqNonSpecInstsAdded 22 # Number of non-speculative instructions added to the IQ +system.cpu.iq.iqSquashedInstsExamined 3408 # Number of squashed instructions iterated over during squash; mainly for profiling +system.cpu.iq.iqSquashedInstsIssued 7 # Number of squashed instructions issued +system.cpu.iq.iqSquashedNonSpecRemoved 6 # Number of squashed non-spec instructions that were removed +system.cpu.iq.iqSquashedOperandsExamined 3586 # Number of squashed operands that are examined and possibly removed from graph +system.cpu.itb.accesses 0 # DTB accesses +system.cpu.itb.hits 0 # DTB hits +system.cpu.itb.misses 0 # DTB misses +system.cpu.itb.read_accesses 0 # DTB read accesses +system.cpu.itb.read_hits 0 # DTB read hits +system.cpu.itb.read_misses 0 # DTB read misses +system.cpu.itb.write_accesses 0 # DTB write accesses +system.cpu.itb.write_hits 0 # DTB write hits +system.cpu.itb.write_misses 0 # DTB write misses +system.cpu.l2cache.ReadExReq_accesses 48 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_avg_miss_latency 34697.916667 # average ReadExReq miss latency +system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 31500 # average ReadExReq mshr miss latency +system.cpu.l2cache.ReadExReq_miss_latency 1665500 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses +system.cpu.l2cache.ReadExReq_misses 48 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 1512000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses +system.cpu.l2cache.ReadExReq_mshr_misses 48 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 386 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 34333.333333 # average ReadReq miss latency +system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 31156.084656 # average ReadReq mshr miss latency +system.cpu.l2cache.ReadReq_hits 8 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 12978000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.979275 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 378 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 11777000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.979275 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 378 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 17 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.UpgradeReq_avg_miss_latency 34235.294118 # average UpgradeReq miss latency +system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 31176.470588 # average UpgradeReq mshr miss latency +system.cpu.l2cache.UpgradeReq_miss_latency 582000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses +system.cpu.l2cache.UpgradeReq_misses 17 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 530000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses +system.cpu.l2cache.UpgradeReq_mshr_misses 17 # number of UpgradeReq MSHR misses +system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked +system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked +system.cpu.l2cache.avg_refs 0.022161 # Average number of references to valid blocks. +system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked +system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked +system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked +system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked +system.cpu.l2cache.cache_copies 0 # number of cache copies performed +system.cpu.l2cache.demand_accesses 434 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 34374.413146 # average overall miss latency +system.cpu.l2cache.demand_avg_mshr_miss_latency 31194.835681 # average overall mshr miss latency +system.cpu.l2cache.demand_hits 8 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 14643500 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.981567 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 426 # number of demand (read+write) misses +system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits +system.cpu.l2cache.demand_mshr_miss_latency 13289000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.981567 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 426 # number of demand (read+write) MSHR misses +system.cpu.l2cache.fast_writes 0 # number of fast writes performed +system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated +system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate +system.cpu.l2cache.overall_accesses 434 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 34374.413146 # average overall miss latency +system.cpu.l2cache.overall_avg_mshr_miss_latency 31194.835681 # average overall mshr miss latency +system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency +system.cpu.l2cache.overall_hits 8 # number of overall hits +system.cpu.l2cache.overall_miss_latency 14643500 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.981567 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 426 # number of overall misses +system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits +system.cpu.l2cache.overall_mshr_miss_latency 13289000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.981567 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 426 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles +system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses +system.cpu.l2cache.replacements 0 # number of replacements +system.cpu.l2cache.sampled_refs 361 # Sample count of references to valid blocks. +system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions +system.cpu.l2cache.tagsinuse 180.652204 # Cycle average of tags in use +system.cpu.l2cache.total_refs 8 # Total number of references to valid blocks. +system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. +system.cpu.l2cache.writebacks 0 # number of writebacks +system.cpu.memDep0.conflictingLoads 67 # Number of conflicting loads. +system.cpu.memDep0.conflictingStores 29 # Number of conflicting stores. +system.cpu.memDep0.insertedLoads 1815 # Number of loads inserted to the mem dependence unit. +system.cpu.memDep0.insertedStores 1394 # Number of stores inserted to the mem dependence unit. +system.cpu.numCycles 23922 # number of cpu cycles simulated +system.cpu.rename.RENAME:BlockCycles 356 # Number of cycles rename is blocking +system.cpu.rename.RENAME:CommittedMaps 5007 # Number of HB maps that are committed +system.cpu.rename.RENAME:IQFullEvents 7 # Number of times rename has blocked due to IQ full +system.cpu.rename.RENAME:IdleCycles 7745 # Number of cycles rename is idle +system.cpu.rename.RENAME:LSQFullEvents 222 # Number of times rename has blocked due to LSQ full +system.cpu.rename.RENAME:RenameLookups 17199 # Number of register rename lookups that rename has made +system.cpu.rename.RENAME:RenamedInsts 10376 # Number of instructions processed by rename +system.cpu.rename.RENAME:RenamedOperands 9321 # Number of destination operands rename has renamed +system.cpu.rename.RENAME:RunCycles 1877 # Number of cycles rename is running +system.cpu.rename.RENAME:SquashCycles 615 # Number of cycles rename is squashing +system.cpu.rename.RENAME:UnblockCycles 273 # Number of cycles rename is unblocking +system.cpu.rename.RENAME:UndoneMaps 4314 # Number of HB maps that are undone due to squashing +system.cpu.rename.RENAME:serializeStallCycles 580 # count of cycles rename stalled for serializing inst +system.cpu.rename.RENAME:serializingInsts 22 # count of serializing insts renamed +system.cpu.rename.RENAME:skidInsts 571 # count of insts added to the skid buffer +system.cpu.rename.RENAME:tempSerializingInsts 22 # count of temporary serializing insts renamed +system.cpu.timesIdled 231 # Number of times that the entire CPU went into an idle state and unscheduled itself +system.cpu.workload.PROG:num_syscalls 9 # Number of system calls + +---------- End Simulation Statistics ---------- diff --git a/tests/quick/00.hello/ref/power/linux/simple-atomic/config.ini b/tests/quick/00.hello/ref/power/linux/simple-atomic/config.ini new file mode 100644 index 0000000000..129c166c3f --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/simple-atomic/config.ini @@ -0,0 +1,91 @@ +[root] +type=Root +children=system +dummy=0 + +[system] +type=System +children=cpu membus physmem +mem_mode=atomic +physmem=system.physmem + +[system.cpu] +type=AtomicSimpleCPU +children=dtb itb tracer workload +UnifiedTLB=true +checker=Null +clock=500 +cpu_id=0 +defer_registration=false +do_checkpoint_insts=true +do_statistics_insts=true +dtb=system.cpu.dtb +function_trace=false +function_trace_start=0 +itb=system.cpu.itb +max_insts_all_threads=0 +max_insts_any_thread=0 +max_loads_all_threads=0 +max_loads_any_thread=0 +numThreads=1 +phase=0 +progress_interval=0 +simulate_data_stalls=false +simulate_inst_stalls=false +system=system +tracer=system.cpu.tracer +width=1 +workload=system.cpu.workload +dcache_port=system.membus.port[2] +icache_port=system.membus.port[1] + +[system.cpu.dtb] +type=PowerTLB +size=64 + +[system.cpu.itb] +type=PowerTLB +size=64 + +[system.cpu.tracer] +type=ExeTracer + +[system.cpu.workload] +type=LiveProcess +cmd=hello +cwd= +egid=100 +env= +errout=cerr +euid=100 +executable=tests/test-progs/hello/bin/power/linux/hello +gid=100 +input=cin +max_stack_size=67108864 +output=cout +pid=100 +ppid=99 +simpoint=0 +system=system +uid=100 + +[system.membus] +type=Bus +block_size=64 +bus_id=0 +clock=1000 +header_cycles=1 +responder_set=false +width=64 +port=system.physmem.port[0] system.cpu.icache_port system.cpu.dcache_port + +[system.physmem] +type=PhysicalMemory +file= +latency=30000 +latency_var=0 +null=false +range=0:134217727 +zero=false +port=system.membus.port[0] + diff --git a/tests/quick/00.hello/ref/power/linux/simple-atomic/simerr b/tests/quick/00.hello/ref/power/linux/simple-atomic/simerr new file mode 100755 index 0000000000..a2692a6c90 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/simple-atomic/simerr @@ -0,0 +1,5 @@ +warn: Sockets disabled, not accepting gdb connections +For more information see: http://www.m5sim.org/warn/d946bea6 +warn: allowing mmap of file @ fd 4294967295. This will break if not /dev/zero. +For more information see: http://www.m5sim.org/warn/3a2134f6 +hack: be nice to actually delete the event here diff --git a/tests/quick/00.hello/ref/power/linux/simple-atomic/simout b/tests/quick/00.hello/ref/power/linux/simple-atomic/simout new file mode 100755 index 0000000000..410d89b19e --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/simple-atomic/simout @@ -0,0 +1,16 @@ +M5 Simulator System + +Copyright (c) 2001-2008 +The Regents of The University of Michigan +All Rights Reserved + + +M5 compiled Oct 15 2009 15:43:13 +M5 revision b43c2c69a460 6694 default hello-world-outputs.patch qtip tip +M5 started Oct 15 2009 15:49:56 +M5 executing on frontend01 +command line: build/POWER_SE/m5.fast -d build/POWER_SE/tests/fast/quick/00.hello/power/linux/simple-atomic -re tests/run.py build/POWER_SE/tests/fast/quick/00.hello/power/linux/simple-atomic +Global frequency set at 1000000000000 ticks per second +info: Entering event queue @ 0. Starting simulation... +Hello world! +Exiting @ tick 2900000 because target called exit() diff --git a/tests/quick/00.hello/ref/power/linux/simple-atomic/stats.txt b/tests/quick/00.hello/ref/power/linux/simple-atomic/stats.txt new file mode 100644 index 0000000000..325ee615a4 --- /dev/null +++ b/tests/quick/00.hello/ref/power/linux/simple-atomic/stats.txt @@ -0,0 +1,36 @@ + +---------- Begin Simulation Statistics ---------- +host_inst_rate 259216 # Simulator instruction rate (inst/s) +host_mem_usage 263696 # Number of bytes of host memory used +host_seconds 0.02 # Real time elapsed on the host +host_tick_rate 128114508 # Simulator tick rate (ticks/s) +sim_freq 1000000000000 # Frequency of simulated ticks +sim_insts 5801 # Number of instructions simulated +sim_seconds 0.000003 # Number of seconds simulated +sim_ticks 2900000 # Number of ticks simulated +system.cpu.dtb.accesses 0 # DTB accesses +system.cpu.dtb.hits 0 # DTB hits +system.cpu.dtb.misses 0 # DTB misses +system.cpu.dtb.read_accesses 0 # DTB read accesses +system.cpu.dtb.read_hits 0 # DTB read hits +system.cpu.dtb.read_misses 0 # DTB read misses +system.cpu.dtb.write_accesses 0 # DTB write accesses +system.cpu.dtb.write_hits 0 # DTB write hits +system.cpu.dtb.write_misses 0 # DTB write misses +system.cpu.idle_fraction 0 # Percentage of idle cycles +system.cpu.itb.accesses 0 # DTB accesses +system.cpu.itb.hits 0 # DTB hits +system.cpu.itb.misses 0 # DTB misses +system.cpu.itb.read_accesses 0 # DTB read accesses +system.cpu.itb.read_hits 0 # DTB read hits +system.cpu.itb.read_misses 0 # DTB read misses +system.cpu.itb.write_accesses 0 # DTB write accesses +system.cpu.itb.write_hits 0 # DTB write hits +system.cpu.itb.write_misses 0 # DTB write misses +system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles +system.cpu.numCycles 5801 # number of cpu cycles simulated +system.cpu.num_insts 5801 # Number of instructions executed +system.cpu.num_refs 2008 # Number of memory references +system.cpu.workload.PROG:num_syscalls 9 # Number of system calls + +---------- End Simulation Statistics ---------- diff --git a/tests/test-progs/hello/bin/power/linux/hello b/tests/test-progs/hello/bin/power/linux/hello new file mode 100755 index 0000000000000000000000000000000000000000..6619ae37f23220b26a5def757049f9d6ba67a516 GIT binary patch literal 625955 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 z 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

9iivkhHn;M*0E^9tC4r&JJmiM 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%0A))@b`hw{w>hI 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 kktE4=Uanf Date: Tue, 20 Oct 2009 15:15:37 -0400 Subject: [PATCH 057/160] Fix stat64 structure on 32-bit X86_SE The st_size entry was in the wrong place (see linux-2.6.29/arch/x86/include/asm/stat.h ) Also, the packed attribute is needed when compiling on a 64-bit machine, otherwise gcc adds extra padding that break the layout of the structure. --- src/arch/x86/linux/linux.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index a810d4a796..238b5e683d 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -142,8 +142,8 @@ class X86Linux32 : public Linux uint32_t st_uid; uint32_t st_gid; uint64_t st_rdev; - int64_t st_size; uint8_t __pad3[4]; + int64_t st_size; uint32_t st_blksize; uint64_t st_blocks; uint32_t st_atimeX; @@ -153,7 +153,7 @@ class X86Linux32 : public Linux uint32_t st_ctimeX; uint32_t st_ctime_nsec; uint64_t st_ino; - } tgt_stat64; + } __attribute__((__packed__)) tgt_stat64; static OpenFlagTransTable openFlagTable[]; From 2b473cb099ad64030a103ee4292e2247f7a3e817 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 20 Oct 2009 14:44:51 -0400 Subject: [PATCH 058/160] hook up stat64 syscall on 32-bit X86_SE --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 2b54843f36..40f70c3fbe 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -702,7 +702,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 192 */ SyscallDesc("mmap2", mmapFunc), /* 193 */ SyscallDesc("truncate64", unimplementedFunc), /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc), - /* 195 */ SyscallDesc("stat64", unimplementedFunc), + /* 195 */ SyscallDesc("stat64", stat64Func), /* 196 */ SyscallDesc("lstat64", unimplementedFunc), /* 197 */ SyscallDesc("fstat64", fstat64Func), /* 198 */ SyscallDesc("lchown32", unimplementedFunc), From 5b6f707a008b4312fd02a4383bf107adfa677d33 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 20 Oct 2009 16:48:00 -0400 Subject: [PATCH 059/160] hook up stat syscall on 64-bit x86_SE --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 40f70c3fbe..14b3fa69b8 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -232,7 +232,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 1 */ SyscallDesc("write", writeFunc), /* 2 */ SyscallDesc("open", openFunc), /* 3 */ SyscallDesc("close", closeFunc), - /* 4 */ SyscallDesc("stat", unimplementedFunc), + /* 4 */ SyscallDesc("stat", stat64Func), /* 5 */ SyscallDesc("fstat", fstat64Func), /* 6 */ SyscallDesc("lstat", unimplementedFunc), /* 7 */ SyscallDesc("poll", unimplementedFunc), From 14691148cd9300ed7a23dd889b9c0173124b30eb Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 21 Oct 2009 13:40:43 -0400 Subject: [PATCH 060/160] Implement X86 sse2 movdqu and movdqa instructions The movdqa instruction should enforce 16-byte alignment. This implementation does not do that. These instructions are needed for most of x86_64 spec2k to run. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 8 +-- .../simd128/integer/data_transfer/move.py | 56 ++++++++++++++++++- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index c23eeccab1..27aabaccc8 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -604,7 +604,7 @@ } // repe (0xF3) 0x4: decode OPCODE_OP_BOTTOM3 { - 0x7: WarnUnimpl::movdqu_Vo_Wo(); + 0x7: MOVDQU(Vo,Wo); default: UD2(); } // operand size (0x66) @@ -616,7 +616,7 @@ 0x4: PUNPCKLQDQ(Vo,Wq); 0x5: PUNPCKHQDQ(Vo,Wq); 0x6: WarnUnimpl::movd_Vo_Ed(); - 0x7: WarnUnimpl::movdqa_Vo_Wo(); + 0x7: MOVDQA(Vo,Wo); } default: UD2(); } @@ -702,7 +702,7 @@ // repe (0xF3) 0x4: decode OPCODE_OP_BOTTOM3 { 0x6: MOVQ(Vq,Wq); - 0x7: WarnUnimpl::movdqu_Wo_Vo(); + 0x7: MOVDQU(Wo,Vo); default: UD2(); } // operand size (0x66) @@ -710,7 +710,7 @@ 0x4: WarnUnimpl::haddpd_Vo_Wo(); 0x5: WarnUnimpl::hsubpd_Vo_Wo(); 0x6: WarnUnimpl::movd_Ed_Vd(); - 0x7: WarnUnimpl::movdqa_Wo_Vo(); + 0x7: MOVDQA(Wo,Vo); default: UD2(); } // repne (0xF2) diff --git a/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py index c34bd42bb2..ec80ffe731 100644 --- a/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py @@ -87,7 +87,59 @@ def macroop MOVQ2DQ_XMM_MMX { movfp xmml, mmxm, dataSize=8 lfpimm xmmh, 0 }; + +def macroop MOVDQA_XMM_XMM { + movfp xmml, xmmlm + movfp xmmh, xmmhm +}; + +def macroop MOVDQA_XMM_M { + ldfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQA_XMM_P { + rdip t7 + ldfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQA_M_XMM { + stfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQA_P_XMM { + rdip t7 + stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_XMM_XMM { + movfp xmml, xmmlm + movfp xmmh, xmmhm +}; + +def macroop MOVDQU_XMM_M { + ldfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_XMM_P { + rdip t7 + ldfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_M_XMM { + stfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_P_XMM { + rdip t7 + stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; ''' -# MOVDQA -# MOVDQU # LDDQU From 87b97f28bd2abc9feb352e7d3f0a85e9bc073912 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 27 Oct 2009 14:11:06 -0400 Subject: [PATCH 061/160] Fix problem with the x86 sse movhpd instruction. The movhpd instruction was writing to the wrong memory offset. --- .../insts/simd128/floating_point/data_transfer/move.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py index 1f4044bde6..09b380fbd2 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py @@ -187,22 +187,21 @@ def macroop MOVHPS_P_XMM { }; def macroop MOVHPD_XMM_M { - ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, sib, "DISPLACEMENT", dataSize=8 }; def macroop MOVHPD_XMM_P { rdip t7 - ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, riprel, "DISPLACEMENT", dataSize=8 }; def macroop MOVHPD_M_XMM { - stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, sib, "DISPLACEMENT", dataSize=8 }; def macroop MOVHPD_P_XMM { rdip t7 - stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 - stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, riprel, "DISPLACEMENT", dataSize=8 }; def macroop MOVLPS_XMM_M { From f9624e49f6d37e42af63a4d7ca401103c67d8027 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 27 Oct 2009 23:50:25 -0700 Subject: [PATCH 062/160] X86: Replace "DISPLACEMENT" with disp in movhpd. --- .../insts/simd128/floating_point/data_transfer/move.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py index 09b380fbd2..ffe084786b 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py @@ -187,21 +187,21 @@ def macroop MOVHPS_P_XMM { }; def macroop MOVHPD_XMM_M { - ldfp xmmh, seg, sib, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPD_XMM_P { rdip t7 - ldfp xmmh, seg, riprel, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVHPD_M_XMM { - stfp xmmh, seg, sib, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPD_P_XMM { rdip t7 - stfp xmmh, seg, riprel, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVLPS_XMM_M { From a02b21977ad6a010478a762c281dbef180f3d249 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 28 Oct 2009 11:56:43 -0700 Subject: [PATCH 063/160] regress: add POWER to regressions --- util/regress | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/regress b/util/regress index 856e9a1a62..347c565cbc 100755 --- a/util/regress +++ b/util/regress @@ -41,7 +41,7 @@ optparser.add_option('-v', '--verbose', dest='verbose', action='store_true', help='echo commands before executing') optparser.add_option('--builds', dest='builds', default='ALPHA_SE,ALPHA_FS,MIPS_SE,' + \ - 'SPARC_SE,SPARC_FS,X86_SE,ARM_SE', + 'POWER_SE,SPARC_SE,SPARC_FS,X86_SE,ARM_SE', help='comma-separated list of build targets to test ' " (default: '%default')" ) optparser.add_option('--variants', dest='variants', From 25d932868998db26054910078721433ab430c836 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 28 Oct 2009 11:56:56 -0700 Subject: [PATCH 064/160] license: Fix license on network model code This mostly was a matter of changing the license owner to Princeton which is as it should have been. The code was originally licensed under the GPL but was relicensed as BSD by Li-Shiuan Peh on July 27, 2009. This relicensing was in an explicit e-mail to Nathan Binkert, Brad Beckmann, Mark Hill, David Wood, and Steve Reinhardt. --- src/mem/ruby/network/Network.cc | 27 +++++++++++++++++ .../garnet-fixed-pipeline/CreditLink_d.hh | 30 +++++++++++++++++-- .../garnet-fixed-pipeline/GarnetNetwork_d.cc | 11 ++----- .../garnet-fixed-pipeline/GarnetNetwork_d.hh | 11 ++----- .../garnet-fixed-pipeline/InputUnit_d.cc | 11 ++----- .../garnet-fixed-pipeline/InputUnit_d.hh | 11 ++----- .../garnet-fixed-pipeline/NetworkHeader.hh | 11 ++----- .../NetworkInterface_d.cc | 11 ++----- .../NetworkInterface_d.hh | 11 ++----- .../garnet-fixed-pipeline/NetworkLink_d.cc | 11 ++----- .../garnet-fixed-pipeline/NetworkLink_d.hh | 11 ++----- .../garnet-fixed-pipeline/OutVcState_d.cc | 11 ++----- .../garnet-fixed-pipeline/OutVcState_d.hh | 11 ++----- .../garnet-fixed-pipeline/OutputUnit_d.cc | 11 ++----- .../garnet-fixed-pipeline/OutputUnit_d.hh | 11 ++----- .../network/garnet-fixed-pipeline/Router_d.cc | 11 ++----- .../network/garnet-fixed-pipeline/Router_d.hh | 10 ++----- .../garnet-fixed-pipeline/RoutingUnit_d.cc | 11 ++----- .../garnet-fixed-pipeline/RoutingUnit_d.hh | 11 ++----- .../garnet-fixed-pipeline/SWallocator_d.cc | 11 ++----- .../garnet-fixed-pipeline/SWallocator_d.hh | 11 ++----- .../network/garnet-fixed-pipeline/Switch_d.cc | 11 ++----- .../network/garnet-fixed-pipeline/Switch_d.hh | 11 ++----- .../garnet-fixed-pipeline/VCallocator_d.cc | 11 ++----- .../garnet-fixed-pipeline/VCallocator_d.hh | 11 ++----- .../garnet-fixed-pipeline/VirtualChannel_d.cc | 11 ++----- .../garnet-fixed-pipeline/VirtualChannel_d.hh | 11 ++----- .../garnet-fixed-pipeline/flitBuffer_d.cc | 11 ++----- .../garnet-fixed-pipeline/flitBuffer_d.hh | 11 ++----- .../network/garnet-fixed-pipeline/flit_d.cc | 11 ++----- .../network/garnet-fixed-pipeline/flit_d.hh | 12 ++------ .../FlexibleConsumer.hh | 10 ++----- .../garnet-flexible-pipeline/GarnetNetwork.cc | 11 ++----- .../garnet-flexible-pipeline/GarnetNetwork.hh | 11 ++----- .../garnet-flexible-pipeline/InVcState.cc | 11 ++----- .../garnet-flexible-pipeline/InVcState.hh | 12 ++------ .../garnet-flexible-pipeline/NetworkConfig.hh | 14 ++++----- .../NetworkInterface.cc | 11 ++----- .../NetworkInterface.hh | 10 ++----- .../garnet-flexible-pipeline/NetworkLink.cc | 11 ++----- .../garnet-flexible-pipeline/NetworkLink.hh | 10 ++----- .../garnet-flexible-pipeline/OutVcState.cc | 11 ++----- .../garnet-flexible-pipeline/OutVcState.hh | 11 ++----- .../garnet-flexible-pipeline/Router.cc | 11 ++----- .../garnet-flexible-pipeline/Router.hh | 11 ++----- .../garnet-flexible-pipeline/VCarbiter.cc | 11 ++----- .../garnet-flexible-pipeline/VCarbiter.hh | 11 ++----- .../network/garnet-flexible-pipeline/flit.cc | 11 ++----- .../network/garnet-flexible-pipeline/flit.hh | 11 ++----- .../garnet-flexible-pipeline/flitBuffer.cc | 11 ++----- .../garnet-flexible-pipeline/flitBuffer.hh | 11 ++----- 51 files changed, 204 insertions(+), 393 deletions(-) diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc index 984ec7ca8a..ac785f6328 100644 --- a/src/mem/ruby/network/Network.cc +++ b/src/mem/ruby/network/Network.cc @@ -1,3 +1,30 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "mem/protocol/MachineType.hh" #include "mem/ruby/network/Network.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh index 387ed0bc1b..c554d7216e 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh @@ -1,9 +1,33 @@ /* - * CreditLink_d.hh + * Copyright (c) 2008 Princeton University + * All rights reserved. * - * Niket Agarwal, Princeton University + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * - * */ + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal + */ + #ifndef CREDIT_LINK_D_H #define CREDIT_LINK_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc index 51393b5761..df643e8001 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * GarnetNetwork_d.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh" #include "mem/protocol/MachineType.hh" #include "mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh index f4b8094437..997f5e3742 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * GarnetNetwork_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef GARNETNETWORK_D_H #define GARNETNETWORK_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc index 0ae32de130..7f344b0b73 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * InputUnit_d.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh index a59ac89d82..beee79b3ec 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * InputUnit_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef INPUT_UNIT_D_H #define INPUT_UNIT_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh index a69dbf1070..62ed9a12c7 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkHeader.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef NETWORK_HEADER_H #define NETWORK_HEADER_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc index 3377ffd1d9..c31b76d62e 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkInterface_d.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh" #include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh index 6252262540..12b8d57e1c 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkInterface_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef NET_INTERFACE_D_H #define NET_INTERFACE_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc index 8382d331f9..dc3c73b0c6 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkLink_d.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" #include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh index 90fb9f6dc7..fed8afbd3a 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkLink_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef NETWORK_LINK_D_H #define NETWORK_LINK_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc index 69e3ae3778..42d9af861a 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * OutVCState_d.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh index dc64b85041..fe6b5fc79d 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * OutVCState_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef OUT_VC_STATE_D_H #define OUT_VC_STATE_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc index eb24508974..e672009c90 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * OutputUnit_d.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh index 78f46d1b5c..beeab8c7f0 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * OutputUnit_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef OUTPUT_UNIT_D_H #define OUTPUT_UNIT_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc index 161e6ecff7..5334de7b99 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * Router_d.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh index 23a8681d90..f9af1abfb5 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * Router_d.hh - * - * Niket Agarwal, Princeton University - * - * */ #ifndef ROUTER_D_H #define ROUTER_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc index 488741055f..9f12ac9cc5 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * Routingunit_d.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh index 091ee90ef5..33c9f3cc45 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * Routerunit_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef ROUTING_UNIT_D_H #define ROUTING_UNIT_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc index dd03783056..c7308597ab 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * SWallocator_d.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh index b1867df7ff..f0ec5d77e0 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * SWallocator_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef SW_ALLOCATOR_D_H #define SW_ALLOCATOR_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc index e1ca648644..11a1969069 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * Switch_d.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh index 2e2f524a03..936972714a 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * Switch_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef SWITCH_D_H #define SWITCH_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc index 810aea1754..4150907d14 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * VCallocator_d.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" #include "mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh index 41e317bff3..ad3c2c95f5 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * VCallocator_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef VC_ALLOCATOR_D_H #define VC_ALLOCATOR_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc index 2e4473a29f..5ce3ca4e5a 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * VirtualChannel_d.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh" VirtualChannel_d::VirtualChannel_d(int id) diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh index 4ac1898e2a..2d81cb7e3f 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * VirtualChannel_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef VIRTUAL_CHANNEL_D_H #define VIRTUAL_CHANNEL_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc index f3ddca0f27..fa189a8cc9 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * flitBuffer_d.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh" flitBuffer_d::flitBuffer_d() diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh index 70a47d5f63..2edea9d764 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * flitBuffer_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef FLIT_BUFFER_D_H #define FLIT_BUFFER_D_H diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc index 3defb8029d..15e0b03943 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * flit_d.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/flit_d.hh" flit_d::flit_d(int id, int vc, int vnet, int size, MsgPtr msg_ptr) diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh index 6f64f49402..39f04052d7 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh +++ b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,16 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * flit_d.hh - * - * Niket Agarwal, Princeton University - * - * */ - - #ifndef FLIT_D_H #define FLIT_D_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh b/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh index f8bf6b949d..82179ec214 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * FlexibleConsumer.hh - * - * Niket Agarwal, Princeton University - * - * */ #ifndef FLEXIBLE_CONSUMER_H #define FLEXIBLE_CONSUMER_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc index e56f5b5e84..5a6b610f9b 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * GarnetNetwork.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh" #include "mem/protocol/MachineType.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh index 194fef7784..c0e4ac6e47 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * GarnetNetwork.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef GARNET_NETWORK_H #define GARNET_NETWORK_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc index cecaf867e3..7fdff46b97 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * InVCState.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/InVcState.hh" InVcState::InVcState(int id) diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh index b7005efea5..67ff6b459a 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,16 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * - * InVCState.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef IN_VC_STATE_H #define IN_VC_STATE_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh index 0a450c0023..2080ef0227 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,16 +24,14 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ /* - * NetworkConfig.hh - * - * Description: This header file is used to define all configuration parameters required by the interconnection network. - * - * Niket Agarwal, Princeton University - * - * */ + * This header file is used to define all configuration parameters + * required by the interconnection network. + */ #ifndef NETWORKCONFIG_H #define NETWORKCONFIG_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc index 597c942b7d..4af5b296f9 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkInterface.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh" #include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh index af4b1d4ebb..8444658eac 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkInterface.hh - * - * Niket Agarwal, Princeton University - * - * */ #ifndef NET_INTERFACE_H #define NET_INTERFACE_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc index ddc92d44c2..598c9e2a44 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkLink.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" #include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh index 6cc35b39da..9f5640a2e7 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,14 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * NetworkLink.hh - * - * Niket Agarwal, Princeton University - * - * */ #ifndef NETWORK_LINK_H #define NETWORK_LINK_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc index 9a95971eb1..a00dd19c17 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * OutVCState.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh" OutVcState::OutVcState(int id) diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh index cb05826dc2..ba68bf2db5 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * OutVCState.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef OUT_VC_STATE_H #define OUT_VC_STATE_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc index ea32e938df..628f19349d 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * Router.cc - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/Router.hh" #include "mem/ruby/slicc_interface/NetworkMessage.hh" #include "mem/ruby/network/garnet-flexible-pipeline/InVcState.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh b/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh index f3cf0036da..69d405ad4a 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * Router.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef ROUTER_H #define ROUTER_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc index 271d6dd380..9064cc4a2e 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * VCarbiter.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh" #include "mem/ruby/network/garnet-flexible-pipeline/Router.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh index 96a03b8dc6..7f7e5e814e 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * VCarbiter.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef VC_ARBITER_H #define VC_ARBITER_H diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc b/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc index 51b8af6c6a..5497263488 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * flit.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/flit.hh" flit::flit(int id, int vc, int vnet, int size, MsgPtr msg_ptr) diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh index aeac2e63bd..a2e6284439 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * flit.hh - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh" #include "mem/ruby/slicc_interface/Message.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc index a0bb71c9dd..c68f8c78b5 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * flitBuffer.C - * - * Niket Agarwal, Princeton University - * - * */ - #include "mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh" flitBuffer::flitBuffer() diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh index 006ba60bdd..c722e161cc 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh +++ b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2008 Princeton University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +24,10 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Niket Agarwal */ -/* - * flitBuffer.hh - * - * Niket Agarwal, Princeton University - * - * */ - #ifndef FLIT_BUFFER_H #define FLIT_BUFFER_H From 3f722b991fcb33ca21330501960406a8a58e2be2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 30 Oct 2009 00:44:55 -0700 Subject: [PATCH 065/160] Syscalls: Make system calls access arguments like a stack, not an array. When accessing arguments for a syscall, the position of an argument depends on the policies of the ISA, how much space preceding arguments took up, and the "alignment" of the index for this particular argument into the number of possible storate locations. This change adjusts getSyscallArg to take its index parameter by reference instead of value and to adjust it to point to the possible location of the next argument on the stack, basically just after the current one. This way, the rules for the new argument can be applied locally without knowing about other arguments since those have already been taken into account implicitly. All system calls have also been changed to reflect the new interface. In a number of cases this made the implementation clearer since it encourages arguments to be collected in one place in order and then used as necessary later, as opposed to scattering them throughout the function or using them in place in long expressions. It also discourages using getSyscallArg over and over to retrieve the same value when a temporary would do the job. --- src/arch/alpha/linux/process.cc | 15 ++- src/arch/alpha/process.cc | 4 +- src/arch/alpha/process.hh | 2 +- src/arch/alpha/tru64/process.cc | 41 +++---- src/arch/arm/linux/process.cc | 10 +- src/arch/arm/linux/process.hh | 2 +- src/arch/arm/process.cc | 4 +- src/arch/arm/process.hh | 2 +- src/arch/mips/linux/process.cc | 19 ++-- src/arch/mips/process.cc | 4 +- src/arch/mips/process.hh | 2 +- src/arch/power/linux/process.cc | 7 +- src/arch/power/linux/process.hh | 2 +- src/arch/power/process.cc | 4 +- src/arch/power/process.hh | 2 +- src/arch/sparc/linux/syscalls.cc | 10 +- src/arch/sparc/process.cc | 8 +- src/arch/sparc/process.hh | 4 +- src/arch/sparc/solaris/process.cc | 3 +- src/arch/x86/linux/syscalls.cc | 11 +- src/arch/x86/process.cc | 19 +++- src/arch/x86/process.hh | 5 +- src/kern/tru64/tru64.hh | 77 ++++++++------ src/sim/process.cc | 6 ++ src/sim/process.hh | 4 +- src/sim/syscall_emul.cc | 153 ++++++++++++++++----------- src/sim/syscall_emul.hh | 170 ++++++++++++++++++------------ 27 files changed, 361 insertions(+), 229 deletions(-) diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 0f09e472b7..a653d7845f 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -48,7 +48,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -67,13 +68,15 @@ static SyscallReturn osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg fpcr(bufPtr); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -94,13 +97,15 @@ static SyscallReturn osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg fpcr(bufPtr); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 6aad45da89..9d75d5fa14 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -193,10 +193,10 @@ AlphaLiveProcess::startup() } AlphaISA::IntReg -AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i) +AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return tc->readIntReg(FirstArgumentReg + i); + return tc->readIntReg(FirstArgumentReg + i++); } void diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index 6d083c5ac2..36b25a48ef 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -44,7 +44,7 @@ class AlphaLiveProcess : public LiveProcess void argsInit(int intSize, int pageSize); public: - AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i); + AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 8fa3cdedac..b039fbe195 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -45,7 +45,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "OSF1"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -62,35 +63,36 @@ static SyscallReturn getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); - unsigned nbytes = process->getSyscallArg(tc, 2); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); + unsigned nbytes = process->getSyscallArg(tc, index); switch (op) { case AlphaTru64::GSI_MAX_CPU: { - TypedBufferArg max_cpu(process->getSyscallArg(tc, 1)); + TypedBufferArg max_cpu(bufPtr); *max_cpu = htog((uint32_t)process->numCpus()); max_cpu.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPUS_IN_BOX: { - TypedBufferArg cpus_in_box(process->getSyscallArg(tc, 1)); + TypedBufferArg cpus_in_box(bufPtr); *cpus_in_box = htog((uint32_t)process->numCpus()); cpus_in_box.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PHYSMEM: { - TypedBufferArg physmem(process->getSyscallArg(tc, 1)); + TypedBufferArg physmem(bufPtr); *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPU_INFO: { - TypedBufferArg - infop(process->getSyscallArg(tc, 1)); + TypedBufferArg infop(bufPtr); infop->current_cpu = htog(0); infop->cpus_in_box = htog(process->numCpus()); @@ -107,14 +109,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_PROC_TYPE: { - TypedBufferArg proc_type(process->getSyscallArg(tc, 1)); + TypedBufferArg proc_type(bufPtr); *proc_type = htog((uint64_t)11); proc_type.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PLATFORM_NAME: { - BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes); + BufferArg bufArg(bufPtr, nbytes); strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); @@ -123,7 +125,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_CLK_TCK: { - TypedBufferArg clk_hz(process->getSyscallArg(tc, 1)); + TypedBufferArg clk_hz(bufPtr); *clk_hz = htog((uint64_t)1024); clk_hz.copyOut(tc->getMemPort()); return 1; @@ -142,12 +144,13 @@ static SyscallReturn setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); switch (op) { case AlphaTru64::SSI_IEEE_FP_CONTROL: warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", - process->getSyscallArg(tc, 1)); + process->getSyscallArg(tc, index)); break; default: @@ -165,17 +168,19 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { using namespace std; - int id = process->getSyscallArg(tc, 0); // table ID - int index = process->getSyscallArg(tc, 1); // index into table + int argIndex = 0; + int id = process->getSyscallArg(tc, argIndex); // table ID + int index = process->getSyscallArg(tc, argIndex); // index into table + Addr bufPtr = process->getSyscallArg(tc, argIndex); // arg 2 is buffer pointer; type depends on table ID - int nel = process->getSyscallArg(tc, 3); // number of elements - int lel = process->getSyscallArg(tc, 4); // expected element size + int nel = process->getSyscallArg(tc, argIndex); // number of elements + int lel = process->getSyscallArg(tc, argIndex); // expected element size switch (id) { case AlphaTru64::TBL_SYSINFO: { if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) return -EINVAL; - TypedBufferArg elp(process->getSyscallArg(tc, 2)); + TypedBufferArg elp(bufPtr); const int clk_hz = one_million; elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index a7f36e18d4..f909d871ae 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -50,7 +50,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -417,7 +418,8 @@ static SyscallReturn setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - uint32_t tlsPtr = process->getSyscallArg(tc, 0); + int index = 0; + uint32_t tlsPtr = process->getSyscallArg(tc, index); tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0, (uint8_t *)&tlsPtr, sizeof(tlsPtr)); @@ -511,12 +513,12 @@ ArmLinuxProcess::startup() } ArmISA::IntReg -ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int i) +ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int &i) { // Linux apparently allows more parameter than the ABI says it should. // This limit may need to be increased even further. assert(i < 6); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/arm/linux/process.hh b/src/arch/arm/linux/process.hh index 53b3781d23..ab836fab22 100644 --- a/src/arch/arm/linux/process.hh +++ b/src/arch/arm/linux/process.hh @@ -44,7 +44,7 @@ class ArmLinuxProcess : public ArmLiveProcess void startup(); - ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i); + ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val); /// The target system's hostname. diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc index cd7cc9736e..702922a433 100644 --- a/src/arch/arm/process.cc +++ b/src/arch/arm/process.cc @@ -324,10 +324,10 @@ ArmLiveProcess::argsInit(int intSize, int pageSize) } ArmISA::IntReg -ArmLiveProcess::getSyscallArg(ThreadContext *tc, int i) +ArmLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 4); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/arm/process.hh b/src/arch/arm/process.hh index 8954d37194..f793892d09 100644 --- a/src/arch/arm/process.hh +++ b/src/arch/arm/process.hh @@ -53,7 +53,7 @@ class ArmLiveProcess : public LiveProcess public: void argsInit(int intSize, int pageSize); - ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i); + ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index dde3a4efde..c2a05b73b7 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -51,7 +51,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename,"m5.eecs.umich.edu"); @@ -70,14 +71,16 @@ static SyscallReturn sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); - // unsigned nbytes = process->getSyscallArg(tc, 2); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + unsigned bufPtr = process->getSyscallArg(tc, index); + // unsigned nbytes = process->getSyscallArg(tc, index); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg fpcr(bufPtr); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -97,15 +100,17 @@ static SyscallReturn sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); - // unsigned nbytes = process->getSyscallArg(tc, 2); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); + // unsigned nbytes = process->getSyscallArg(tc, index); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg fpcr(bufPtr); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): " diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index b9f608922e..d96b0c81c6 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -147,10 +147,10 @@ MipsLiveProcess::argsInit(int intSize, int pageSize) MipsISA::IntReg -MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i) +MipsLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return tc->readIntReg(FirstArgumentReg + i); + return tc->readIntReg(FirstArgumentReg + i++); } void diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index b8f4de20ab..f35ec85542 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -50,7 +50,7 @@ class MipsLiveProcess : public LiveProcess void argsInit(int intSize, int pageSize); public: - MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i); + MipsISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc index b03ccfc8c1..504d0e3342 100644 --- a/src/arch/power/linux/process.cc +++ b/src/arch/power/linux/process.cc @@ -52,7 +52,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -437,12 +438,12 @@ PowerLinuxProcess::startup() } PowerISA::IntReg -PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int i) +PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int &i) { // Linux apparently allows more parameter than the ABI says it should. // This limit may need to be increased even further. assert(i < 6); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/power/linux/process.hh b/src/arch/power/linux/process.hh index 78b0eef7fe..db6759a773 100644 --- a/src/arch/power/linux/process.hh +++ b/src/arch/power/linux/process.hh @@ -46,7 +46,7 @@ class PowerLinuxProcess : public PowerLiveProcess void startup(); - PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i); + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); /// Array of syscall descriptors, indexed by call number. diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index 8828a1a934..92f993e4c7 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -266,10 +266,10 @@ PowerLiveProcess::argsInit(int intSize, int pageSize) } PowerISA::IntReg -PowerLiveProcess::getSyscallArg(ThreadContext *tc, int i) +PowerLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 5); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh index dae776c4c4..ede75f05f1 100644 --- a/src/arch/power/process.hh +++ b/src/arch/power/process.hh @@ -50,7 +50,7 @@ class PowerLiveProcess : public LiveProcess public: void argsInit(int intSize, int pageSize); - PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i); + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index c508039762..874ddc0053 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -41,7 +41,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -59,9 +60,10 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { const IntReg id = htog(100); - Addr ruid = p->getSyscallArg(tc, 0); - Addr euid = p->getSyscallArg(tc, 1); - Addr suid = p->getSyscallArg(tc, 2); + int index = 0; + Addr ruid = p->getSyscallArg(tc, index); + Addr euid = p->getSyscallArg(tc, index); + Addr suid = p->getSyscallArg(tc, index); //Handle the EFAULT case //Set the ruid if(ruid) diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 89e8535737..7e01f6b07a 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -514,10 +514,10 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc) } IntReg -Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int i) +Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return bits(tc->readIntReg(FirstArgumentReg + i), 31, 0); + return bits(tc->readIntReg(FirstArgumentReg + i++), 31, 0); } void @@ -528,10 +528,10 @@ Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val) } IntReg -Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return tc->readIntReg(FirstArgumentReg + i); + return tc->readIntReg(FirstArgumentReg + i++); } void diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index fdb9734bac..cca312e0ab 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -95,7 +95,7 @@ class Sparc32LiveProcess : public SparcLiveProcess void flushWindows(ThreadContext *tc); - SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; @@ -123,7 +123,7 @@ class Sparc64LiveProcess : public SparcLiveProcess void flushWindows(ThreadContext *tc); - SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index eafb488df7..24abd86879 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -48,7 +48,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "SunOS"); strcpy(name->nodename, "m5.eecs.umich.edu"); diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 14b3fa69b8..4c29559fb1 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -68,7 +68,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -94,8 +95,9 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, }; //First argument is the code, second is the address - int code = process->getSyscallArg(tc, 0); - uint64_t addr = process->getSyscallArg(tc, 1); + int index = 0; + int code = process->getSyscallArg(tc, index); + uint64_t addr = process->getSyscallArg(tc, index); uint64_t fsBase, gsBase; TranslatingPort *p = tc->getMemPort(); switch(code) @@ -159,7 +161,8 @@ setThreadArea32Func(SyscallDesc *desc, int callnum, assert((maxTLSEntry + 1) * sizeof(uint64_t) <= x86lp->gdtSize()); - TypedBufferArg userDesc(process->getSyscallArg(tc, 0)); + int argIndex = 0; + TypedBufferArg userDesc(process->getSyscallArg(tc, argIndex)); TypedBufferArg gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t), numTLSEntries * sizeof(uint64_t)); diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index f7678443d1..f7b3ce24ae 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -698,10 +698,10 @@ X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value) } X86ISA::IntReg -X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < NumArgumentRegs); - return tc->readIntReg(ArgumentReg[i]); + return tc->readIntReg(ArgumentReg[i++]); } void @@ -712,10 +712,21 @@ X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) } X86ISA::IntReg -I386LiveProcess::getSyscallArg(ThreadContext *tc, int i) +I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < NumArgumentRegs32); - return tc->readIntReg(ArgumentReg32[i]); + return tc->readIntReg(ArgumentReg32[i++]); +} + +X86ISA::IntReg +I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width) +{ + assert(width == 32 || width == 64); + assert(i < NumArgumentRegs); + uint64_t retVal = tc->readIntReg(ArgumentReg32[i++]) & mask(32); + if (width == 64) + retVal |= ((uint64_t)tc->readIntReg(ArgumentReg[i++]) << 32); + return retVal; } void diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index cd6d99e667..4d031bd5a3 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -105,7 +105,7 @@ namespace X86ISA void argsInit(int intSize, int pageSize); void startup(); - X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; @@ -130,7 +130,8 @@ namespace X86ISA void startup(); void syscall(int64_t callnum, ThreadContext *tc); - X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i); + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width); void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; } diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh index c2bdd27764..033f309461 100644 --- a/src/kern/tru64/tru64.hh +++ b/src/kern/tru64/tru64.hh @@ -440,10 +440,11 @@ class Tru64 : public OperatingSystem #ifdef __CYGWIN__ panic("getdirent not implemented on cygwin!"); #else - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); - Addr tgt_buf = process->getSyscallArg(tc, 1); - int tgt_nbytes = process->getSyscallArg(tc, 2); - Addr tgt_basep = process->getSyscallArg(tc, 3); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); + Addr tgt_buf = process->getSyscallArg(tc, index); + int tgt_nbytes = process->getSyscallArg(tc, index); + Addr tgt_basep = process->getSyscallArg(tc, index); char * const host_buf = new char[tgt_nbytes]; @@ -498,7 +499,8 @@ class Tru64 : public OperatingSystem { using namespace TheISA; - TypedBufferArg sc(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg sc(process->getSyscallArg(tc, index)); sc.copyIn(tc->getMemPort()); @@ -530,7 +532,8 @@ class Tru64 : public OperatingSystem { using namespace TheISA; - TypedBufferArg argp(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg argp(process->getSyscallArg(tc, index)); argp.copyIn(tc->getMemPort()); @@ -578,9 +581,10 @@ class Tru64 : public OperatingSystem using namespace std; using namespace TheISA; + int index = 0; TypedBufferArg - attrp(process->getSyscallArg(tc, 0)); - TypedBufferArg configptr_ptr(process->getSyscallArg(tc, 1)); + attrp(process->getSyscallArg(tc, index)); + TypedBufferArg configptr_ptr(process->getSyscallArg(tc, index)); attrp.copyIn(tc->getMemPort()); @@ -712,10 +716,11 @@ class Tru64 : public OperatingSystem using namespace std; using namespace TheISA; + int index = 0; TypedBufferArg - attrp(process->getSyscallArg(tc, 0)); - TypedBufferArg kidp(process->getSyscallArg(tc, 1)); - int thread_index = process->getSyscallArg(tc, 2); + attrp(process->getSyscallArg(tc, index)); + TypedBufferArg kidp(process->getSyscallArg(tc, index)); + int thread_index = process->getSyscallArg(tc, index); // get attribute args attrp.copyIn(tc->getMemPort()); @@ -834,11 +839,12 @@ class Tru64 : public OperatingSystem { using namespace std; - uint64_t tid = process->getSyscallArg(tc, 0); - uint64_t secs = process->getSyscallArg(tc, 1); - uint64_t flags = process->getSyscallArg(tc, 2); - uint64_t action = process->getSyscallArg(tc, 3); - uint64_t usecs = process->getSyscallArg(tc, 4); + int index = 0; + uint64_t tid = process->getSyscallArg(tc, index); + uint64_t secs = process->getSyscallArg(tc, index); + uint64_t flags = process->getSyscallArg(tc, index); + uint64_t action = process->getSyscallArg(tc, index); + uint64_t usecs = process->getSyscallArg(tc, index); cout << tc->getCpuPtr()->name() << ": nxm_thread_block " << tid << " " << secs << " " << flags << " " << action << " " << usecs << endl; @@ -853,11 +859,12 @@ class Tru64 : public OperatingSystem { using namespace std; - Addr uaddr = process->getSyscallArg(tc, 0); - uint64_t val = process->getSyscallArg(tc, 1); - uint64_t secs = process->getSyscallArg(tc, 2); - uint64_t usecs = process->getSyscallArg(tc, 3); - uint64_t flags = process->getSyscallArg(tc, 4); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); + uint64_t val = process->getSyscallArg(tc, index); + uint64_t secs = process->getSyscallArg(tc, index); + uint64_t usecs = process->getSyscallArg(tc, index); + uint64_t flags = process->getSyscallArg(tc, index); BaseCPU *cpu = tc->getCpuPtr(); @@ -876,7 +883,8 @@ class Tru64 : public OperatingSystem { using namespace std; - Addr uaddr = process->getSyscallArg(tc, 0); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); cout << tc->getCpuPtr()->name() << ": nxm_unblock " << hex << uaddr << dec << endl; @@ -977,7 +985,8 @@ class Tru64 : public OperatingSystem m5_mutex_lockFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr uaddr = process->getSyscallArg(tc, 0); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); m5_lock_mutex(uaddr, process, tc); @@ -994,7 +1003,8 @@ class Tru64 : public OperatingSystem { using namespace TheISA; - Addr uaddr = process->getSyscallArg(tc, 0); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); TypedBufferArg lockp(uaddr); lockp.copyIn(tc->getMemPort()); @@ -1014,7 +1024,8 @@ class Tru64 : public OperatingSystem m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr uaddr = process->getSyscallArg(tc, 0); + int index = 0; + Addr uaddr = process->getSyscallArg(tc, index); m5_unlock_mutex(uaddr, process, tc); @@ -1026,7 +1037,8 @@ class Tru64 : public OperatingSystem m5_cond_signalFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr cond_addr = process->getSyscallArg(tc, 0); + int index = 0; + Addr cond_addr = process->getSyscallArg(tc, index); // Wake up one process waiting on the condition variable. activate_waiting_context(cond_addr, process); @@ -1039,7 +1051,8 @@ class Tru64 : public OperatingSystem m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr cond_addr = process->getSyscallArg(tc, 0); + int index = 0; + Addr cond_addr = process->getSyscallArg(tc, index); activate_waiting_context(cond_addr, process, true); @@ -1053,8 +1066,9 @@ class Tru64 : public OperatingSystem { using namespace TheISA; - Addr cond_addr = process->getSyscallArg(tc, 0); - Addr lock_addr = process->getSyscallArg(tc, 1); + int index = 0; + Addr cond_addr = process->getSyscallArg(tc, index); + Addr lock_addr = process->getSyscallArg(tc, index); TypedBufferArg condp(cond_addr); TypedBufferArg lockp(lock_addr); @@ -1086,10 +1100,11 @@ class Tru64 : public OperatingSystem indirectSyscallFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int new_callnum = process->getSyscallArg(tc, 0); + int index = 0; + int new_callnum = process->getSyscallArg(tc, index); for (int i = 0; i < 5; ++i) - process->setSyscallArg(tc, i, process->getSyscallArg(tc, i+1)); + process->setSyscallArg(tc, i, process->getSyscallArg(tc, index)); SyscallDesc *new_desc = process->getDesc(new_callnum); diff --git a/src/sim/process.cc b/src/sim/process.cc index cf0f2b84d2..e71d6441f9 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -647,6 +647,12 @@ LiveProcess::syscall(int64_t callnum, ThreadContext *tc) desc->doSyscall(callnum, this, tc); } +IntReg +LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width) +{ + return getSyscallArg(tc, i); +} + LiveProcess * LiveProcess::create(LiveProcessParams * params) { diff --git a/src/sim/process.hh b/src/sim/process.hh index 7922ce0732..ab9d64cf33 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -325,7 +325,9 @@ class LiveProcess : public Process std::string getcwd() const { return cwd; } virtual void syscall(int64_t callnum, ThreadContext *tc); - virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int i) = 0; + + virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0; + virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width); virtual void setSyscallArg(ThreadContext *tc, int i, TheISA::IntReg val) = 0; virtual void setSyscallReturn(ThreadContext *tc, diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 13ad043111..d25f7b9fa1 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -52,11 +52,14 @@ using namespace TheISA; void SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc) { + int index = 0; DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", curTick, tc->getCpuPtr()->name(), name, - process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1), - process->getSyscallArg(tc, 2), process->getSyscallArg(tc, 3)); + process->getSyscallArg(tc, index), + process->getSyscallArg(tc, index), + process->getSyscallArg(tc, index), + process->getSyscallArg(tc, index)); SyscallReturn retval = (*funcPtr)(this, callnum, process, tc); @@ -82,8 +85,9 @@ SyscallReturn ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { + int index = 0; warn("ignoring syscall %s(%d, %d, ...)", desc->name, - process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1)); + process->getSyscallArg(tc, index), process->getSyscallArg(tc, index)); return 0; } @@ -95,8 +99,9 @@ exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { if (process->system->numRunningContexts() == 1) { // Last running context... exit simulator + int index = 0; exitSimLoop("target called exit()", - process->getSyscallArg(tc, 0) & 0xff); + process->getSyscallArg(tc, index) & 0xff); } else { // other running threads... just halt this one tc->halt(); @@ -112,8 +117,9 @@ exitGroupFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { // really should just halt all thread contexts belonging to this // process in case there's another process running... + int index = 0; exitSimLoop("target called exit()", - process->getSyscallArg(tc, 0) & 0xff); + process->getSyscallArg(tc, index) & 0xff); return 1; } @@ -130,7 +136,8 @@ SyscallReturn brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { // change brk addr to first arg - Addr new_brk = p->getSyscallArg(tc, 0); + int index = 0; + Addr new_brk = p->getSyscallArg(tc, index); // in Linux at least, brk(0) returns the current break value // (note that the syscall and the glibc function have different behavior) @@ -174,7 +181,8 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int target_fd = p->getSyscallArg(tc, 0); + int index = 0; + int target_fd = p->getSyscallArg(tc, index); int status = close(p->sim_fd(target_fd)); if (status >= 0) p->free_fd(target_fd); @@ -185,9 +193,11 @@ closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(p->getSyscallArg(tc, 0)); - int nbytes = p->getSyscallArg(tc, 2); - BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes); + int index = 0; + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + Addr bufPtr = p->getSyscallArg(tc, index); + int nbytes = p->getSyscallArg(tc, index); + BufferArg bufArg(bufPtr, nbytes); int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); @@ -200,9 +210,11 @@ readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(p->getSyscallArg(tc, 0)); - int nbytes = p->getSyscallArg(tc, 2); - BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes); + int index = 0; + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + Addr bufPtr = p->getSyscallArg(tc, index); + int nbytes = p->getSyscallArg(tc, index); + BufferArg bufArg(bufPtr, nbytes); bufArg.copyIn(tc->getMemPort()); @@ -217,9 +229,10 @@ writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(p->getSyscallArg(tc, 0)); - uint64_t offs = p->getSyscallArg(tc, 1); - int whence = p->getSyscallArg(tc, 2); + int index = 0; + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + uint64_t offs = p->getSyscallArg(tc, index); + int whence = p->getSyscallArg(tc, index); off_t result = lseek(fd, offs, whence); @@ -230,11 +243,12 @@ lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn _llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int fd = p->sim_fd(p->getSyscallArg(tc, 0)); - uint64_t offset_high = p->getSyscallArg(tc, 1); - uint32_t offset_low = p->getSyscallArg(tc, 2); - Addr result_ptr = p->getSyscallArg(tc, 3); - int whence = p->getSyscallArg(tc, 4); + int index = 0; + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + uint64_t offset_high = p->getSyscallArg(tc, index); + uint32_t offset_low = p->getSyscallArg(tc, index); + Addr result_ptr = p->getSyscallArg(tc, index); + int whence = p->getSyscallArg(tc, index); uint64_t offset = (offset_high << 32) | offset_low; @@ -273,8 +287,10 @@ const char *hostname = "m5.eecs.umich.edu"; SyscallReturn gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - int name_len = p->getSyscallArg(tc, 1); - BufferArg name(p->getSyscallArg(tc, 0), name_len); + int index = 0; + Addr bufPtr = p->getSyscallArg(tc, index); + int name_len = p->getSyscallArg(tc, index); + BufferArg name(bufPtr, name_len); strncpy((char *)name.bufferPtr(), hostname, name_len); @@ -287,8 +303,10 @@ SyscallReturn getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { int result = 0; - unsigned long size = p->getSyscallArg(tc, 1); - BufferArg buf(p->getSyscallArg(tc, 0), size); + int index; + Addr bufPtr = p->getSyscallArg(tc, index); + unsigned long size = p->getSyscallArg(tc, index); + BufferArg buf(bufPtr, size); // Is current working directory defined? string cwd = p->getcwd(); @@ -320,14 +338,17 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return (TheISA::IntReg)-EFAULT; // Adjust path for current working directory path = p->fullPath(path); - size_t bufsiz = p->getSyscallArg(tc, 2); - BufferArg buf(p->getSyscallArg(tc, 1), bufsiz); + Addr bufPtr = p->getSyscallArg(tc, index); + size_t bufsiz = p->getSyscallArg(tc, index); + + BufferArg buf(bufPtr, bufsiz); int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz); @@ -341,7 +362,8 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return (TheISA::IntReg)-EFAULT; // Adjust path for current working directory @@ -357,13 +379,14 @@ mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return (TheISA::IntReg)-EFAULT; // Adjust path for current working directory path = p->fullPath(path); - mode_t mode = p->getSyscallArg(tc, 1); + mode_t mode = p->getSyscallArg(tc, index); int result = mkdir(path.c_str(), mode); return (result == -1) ? -errno : result; @@ -374,12 +397,13 @@ renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string old_name; - if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, index))) return -EFAULT; string new_name; - if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, 1))) + if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, index))) return -EFAULT; // Adjust path for current working directory @@ -395,10 +419,11 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return -EFAULT; - off_t length = p->getSyscallArg(tc, 1); + off_t length = p->getSyscallArg(tc, index); // Adjust path for current working directory path = p->fullPath(path); @@ -411,12 +436,13 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); if (fd < 0) return -EBADF; - off_t length = process->getSyscallArg(tc, 1); + off_t length = process->getSyscallArg(tc, index); int result = ftruncate(fd, length); return (result == -1) ? -errno : result; @@ -426,13 +452,13 @@ SyscallReturn ftruncate64Func(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); if (fd < 0) return -EBADF; - // I'm not sure why, but the length argument is in arg reg 3 - loff_t length = process->getSyscallArg(tc, 3); + loff_t length = process->getSyscallArg(tc, index, 64); int result = ftruncate64(fd, length); return (result == -1) ? -errno : result; @@ -454,13 +480,14 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { string path; - if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index))) return -EFAULT; /* XXX endianess */ - uint32_t owner = p->getSyscallArg(tc, 1); + uint32_t owner = p->getSyscallArg(tc, index); uid_t hostOwner = owner; - uint32_t group = p->getSyscallArg(tc, 2); + uint32_t group = p->getSyscallArg(tc, index); gid_t hostGroup = group; // Adjust path for current working directory @@ -473,15 +500,16 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); if (fd < 0) return -EBADF; /* XXX endianess */ - uint32_t owner = process->getSyscallArg(tc, 1); + uint32_t owner = process->getSyscallArg(tc, index); uid_t hostOwner = owner; - uint32_t group = process->getSyscallArg(tc, 2); + uint32_t group = process->getSyscallArg(tc, index); gid_t hostGroup = group; int result = fchown(fd, hostOwner, hostGroup); @@ -492,11 +520,12 @@ fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) SyscallReturn dupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); if (fd < 0) return -EBADF; - Process::FdMap *fdo = process->sim_fd_obj(process->getSyscallArg(tc, 0)); + Process::FdMap *fdo = process->sim_fd_obj(fd); int result = dup(fd); return (result == -1) ? -errno : @@ -508,12 +537,13 @@ SyscallReturn fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) return -EBADF; - int cmd = process->getSyscallArg(tc, 1); + int cmd = process->getSyscallArg(tc, index); switch (cmd) { case 0: // F_DUPFD // if we really wanted to support this, we'd need to do it @@ -550,12 +580,13 @@ SyscallReturn fcntl64Func(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) return -EBADF; - int cmd = process->getSyscallArg(tc, 1); + int cmd = process->getSyscallArg(tc, index); switch (cmd) { case 33: //F_GETLK64 warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd); @@ -639,7 +670,8 @@ setuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { // can't fathom why a benchmark would call this. - warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, 0)); + int index = 0; + warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, index)); return 0; } @@ -695,17 +727,20 @@ SyscallReturn cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { + int index = 0; + IntReg flags = process->getSyscallArg(tc, index); + IntReg newStack = process->getSyscallArg(tc, index); + DPRINTF(SyscallVerbose, "In sys_clone:\n"); - DPRINTF(SyscallVerbose, " Flags=%llx\n", process->getSyscallArg(tc, 0)); - DPRINTF(SyscallVerbose, " Child stack=%llx\n", - process->getSyscallArg(tc, 1)); + DPRINTF(SyscallVerbose, " Flags=%llx\n", flags); + DPRINTF(SyscallVerbose, " Child stack=%llx\n", newStack); - if (process->getSyscallArg(tc, 0) != 0x10f00) { + if (flags != 0x10f00) { warn("This sys_clone implementation assumes flags " "CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD " "(0x10f00), and may not work correctly with given flags " - "0x%llx\n", process->getSyscallArg(tc, 0)); + "0x%llx\n", flags); } ThreadContext* ctc; // child thread context @@ -738,7 +773,7 @@ cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process, #endif // Set up stack register - ctc->setIntReg(TheISA::StackPointerReg, process->getSyscallArg(tc, 1)); + ctc->setIntReg(TheISA::StackPointerReg, newStack); // Set up syscall return values in parent and child ctc->setIntReg(ReturnValueReg, 0); // return value, child diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 0c51c7dec9..8fe53e2666 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -481,8 +481,9 @@ SyscallReturn ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); - unsigned req = process->getSyscallArg(tc, 1); + int index = 0; + int fd = process->getSyscallArg(tc, index); + unsigned req = process->getSyscallArg(tc, index); DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); @@ -517,7 +518,9 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) return -EFAULT; if (path == "/dev/sysdev0") { @@ -527,8 +530,8 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return -ENOENT; } - int tgtFlags = process->getSyscallArg(tc, 1); - int mode = process->getSyscallArg(tc, 2); + int tgtFlags = process->getSyscallArg(tc, index); + int mode = process->getSyscallArg(tc, index); int hostFlags = 0; // translate open flags @@ -573,14 +576,16 @@ sysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg sysinfo(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg + sysinfo(process->getSyscallArg(tc, index)); - sysinfo->uptime=seconds_since_epoch; - sysinfo->totalram=process->system->memSize(); + sysinfo->uptime=seconds_since_epoch; + sysinfo->totalram=process->system->memSize(); - sysinfo.copyOut(tc->getMemPort()); + sysinfo.copyOut(tc->getMemPort()); - return 0; + return 0; } /// Target chmod() handler. @@ -591,10 +596,13 @@ chmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { return -EFAULT; + } - uint32_t mode = process->getSyscallArg(tc, 1); + uint32_t mode = process->getSyscallArg(tc, index); mode_t hostMode = 0; // XXX translate mode flags via OS::something??? @@ -618,13 +626,14 @@ SyscallReturn fchmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; } - uint32_t mode = process->getSyscallArg(tc, 1); + uint32_t mode = process->getSyscallArg(tc, index); mode_t hostMode = 0; // XXX translate mode flags via OS::someting??? @@ -643,10 +652,11 @@ template SyscallReturn mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - Addr start = process->getSyscallArg(tc, 0); - uint64_t old_length = process->getSyscallArg(tc, 1); - uint64_t new_length = process->getSyscallArg(tc, 2); - uint64_t flags = process->getSyscallArg(tc, 3); + int index = 0; + Addr start = process->getSyscallArg(tc, index); + uint64_t old_length = process->getSyscallArg(tc, index); + uint64_t new_length = process->getSyscallArg(tc, index); + uint64_t flags = process->getSyscallArg(tc, index); if ((start % TheISA::VMPageSize != 0) || (new_length % TheISA::VMPageSize != 0)) { @@ -692,8 +702,12 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -704,8 +718,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStatBuf(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + copyOutStatBuf(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -719,8 +732,11 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) return -EFAULT; + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -736,8 +752,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStat64Buf(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + copyOutStat64Buf(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -749,7 +764,9 @@ SyscallReturn fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; @@ -766,8 +783,7 @@ fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStat64Buf(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf, (fd == 1)); + copyOutStat64Buf(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1)); return 0; } @@ -781,8 +797,12 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -793,8 +813,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStatBuf(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + copyOutStatBuf(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -807,8 +826,12 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -824,8 +847,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStat64Buf(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + copyOutStat64Buf(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -836,7 +858,9 @@ SyscallReturn fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); + Addr bufPtr = process->getSyscallArg(tc, index); DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); @@ -849,8 +873,7 @@ fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - copyOutStatBuf(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf, (fd == 1)); + copyOutStatBuf(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1)); return 0; } @@ -864,8 +887,12 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } + Addr bufPtr = process->getSyscallArg(tc, index); // Adjust path for current working directory path = process->fullPath(path); @@ -876,8 +903,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - OS::copyOutStatfsBuf(tc->getMemPort(), - (Addr)(process->getSyscallArg(tc, 1)), &hostBuf); + OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -889,7 +915,9 @@ SyscallReturn fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->sim_fd(process->getSyscallArg(tc, 0)); + int index = 0; + int fd = process->sim_fd(process->getSyscallArg(tc, index)); + Addr bufPtr = process->getSyscallArg(tc, index); if (fd < 0) return -EBADF; @@ -900,8 +928,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process, if (result < 0) return -errno; - OS::copyOutStatfsBuf(tc->getMemPort(), process->getSyscallArg(tc, 1), - &hostBuf); + OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf); return 0; } @@ -913,15 +940,16 @@ SyscallReturn writevFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int fd = process->getSyscallArg(tc, 0); + int index = 0; + int fd = process->getSyscallArg(tc, index); if (fd < 0 || process->sim_fd(fd) < 0) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; } TranslatingPort *p = tc->getMemPort(); - uint64_t tiov_base = process->getSyscallArg(tc, 1); - size_t count = process->getSyscallArg(tc, 2); + uint64_t tiov_base = process->getSyscallArg(tc, index); + size_t count = process->getSyscallArg(tc, index); struct iovec hiov[count]; for (size_t i = 0; i < count; ++i) { typename OS::tgt_iovec tiov; @@ -962,12 +990,13 @@ template SyscallReturn mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - Addr start = p->getSyscallArg(tc, 0); - uint64_t length = p->getSyscallArg(tc, 1); - // int prot = p->getSyscallArg(tc, 2); - int flags = p->getSyscallArg(tc, 3); - // int fd = p->sim_fd(p->getSyscallArg(tc, 4)); - // int offset = p->getSyscallArg(tc, 5); + int index = 0; + Addr start = p->getSyscallArg(tc, index); + uint64_t length = p->getSyscallArg(tc, index); + index++; // int prot = p->getSyscallArg(tc, index); + int flags = p->getSyscallArg(tc, index); + int fd = p->sim_fd(p->getSyscallArg(tc, index)); + // int offset = p->getSyscallArg(tc, index); if ((start % TheISA::VMPageSize) != 0 || @@ -995,7 +1024,7 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) if (!(flags & OS::TGT_MAP_ANONYMOUS)) { warn("allowing mmap of file @ fd %d. " - "This will break if not /dev/zero.", p->getSyscallArg(tc, 4)); + "This will break if not /dev/zero.", fd); } return start; @@ -1007,8 +1036,9 @@ SyscallReturn getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned resource = process->getSyscallArg(tc, 0); - TypedBufferArg rlp(process->getSyscallArg(tc, 1)); + int index = 0; + unsigned resource = process->getSyscallArg(tc, index); + TypedBufferArg rlp(process->getSyscallArg(tc, index)); switch (resource) { case OS::TGT_RLIMIT_STACK: @@ -1042,7 +1072,8 @@ SyscallReturn gettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg tp(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg tp(process->getSyscallArg(tc, index)); getElapsedTime(tp->tv_sec, tp->tv_usec); tp->tv_sec += seconds_since_epoch; @@ -1063,10 +1094,14 @@ utimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { std::string path; - if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0))) - return -EFAULT; + int index = 0; + if (!tc->getMemPort()->tryReadString(path, + process->getSyscallArg(tc, index))) { + return -EFAULT; + } - TypedBufferArg tp(process->getSyscallArg(tc, 1)); + TypedBufferArg + tp(process->getSyscallArg(tc, index)); tp.copyIn(tc->getMemPort()); struct timeval hostTimeval[2]; @@ -1092,8 +1127,9 @@ SyscallReturn getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - int who = process->getSyscallArg(tc, 0); // THREAD, SELF, or CHILDREN - TypedBufferArg rup(process->getSyscallArg(tc, 1)); + int index = 0; + int who = process->getSyscallArg(tc, index); // THREAD, SELF, or CHILDREN + TypedBufferArg rup(process->getSyscallArg(tc, index)); rup->ru_utime.tv_sec = 0; rup->ru_utime.tv_usec = 0; @@ -1143,7 +1179,8 @@ SyscallReturn timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg bufp(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg bufp(process->getSyscallArg(tc, index)); // Fill in the time structure (in clocks) int64_t clocks = curTick * OS::_SC_CLK_TCK / Clock::Int::s; @@ -1172,7 +1209,8 @@ timeFunc(SyscallDesc *desc, int callnum, LiveProcess *process, getElapsedTime(sec, usec); sec += seconds_since_epoch; - Addr taddr = (Addr)process->getSyscallArg(tc, 0); + int index = 0; + Addr taddr = (Addr)process->getSyscallArg(tc, index); if(taddr != 0) { typename OS::time_t t = sec; t = htog(t); From d6ff7929b30cde7bce1b3f3be89e1ef6eda82a2d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 31 Oct 2009 13:20:22 -0700 Subject: [PATCH 066/160] Syscalls: Fix a warning turned error about an unused variable in m5.fast. --- src/sim/syscall_emul.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index d25f7b9fa1..fae3586a40 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -52,7 +52,9 @@ using namespace TheISA; void SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc) { +#if TRACING_ON int index = 0; +#endif DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", curTick, tc->getCpuPtr()->name(), name, From 9ad3acab5ea79effe27fba240d8f89aadc138f6f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 12:31:55 -0400 Subject: [PATCH 067/160] SysCalls: Implement truncate64 system call This uses the new stack-based argument infrastructure. Tested on x86 and x86_64. --- src/sim/syscall_emul.cc | 19 +++++++++++++++++++ src/sim/syscall_emul.hh | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index fae3586a40..cc8d99bcdc 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -450,6 +450,25 @@ ftruncateFunc(SyscallDesc *desc, int num, return (result == -1) ? -errno : result; } +SyscallReturn +truncate64Func(SyscallDesc *desc, int num, + LiveProcess *process, ThreadContext *tc) +{ + int index = 0; + string path; + + if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, index))) + return -EFAULT; + + loff_t length = process->getSyscallArg(tc, index, 64); + + // Adjust path for current working directory + path = process->fullPath(path); + + int result = truncate64(path.c_str(), length); + return (result == -1) ? -errno : result; +} + SyscallReturn ftruncate64Func(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 8fe53e2666..27c26afb0f 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -260,6 +260,10 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); +/// Target truncate64() handler. +SyscallReturn truncate64Func(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + /// Target ftruncate64() handler. SyscallReturn ftruncate64Func(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); From cf269025f9e51eebb56d04fea6994fd72b1be4f9 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 12:51:13 -0400 Subject: [PATCH 068/160] X86: Hookup truncate/ftruncate syscalls on X86 This patch hooks up the truncate, ftruncate, truncate64 and ftruncate64 system calls on 32-bit and 64-bit X86. These have been tested on both architectures. ftruncate/ftruncate64 is needed for the f90 spec2k benchmarks. --- src/arch/x86/linux/syscalls.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 4c29559fb1..2a7fd8d4ea 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -307,8 +307,8 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 73 */ SyscallDesc("flock", unimplementedFunc), /* 74 */ SyscallDesc("fsync", unimplementedFunc), /* 75 */ SyscallDesc("fdatasync", unimplementedFunc), - /* 76 */ SyscallDesc("truncate", unimplementedFunc), - /* 77 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 76 */ SyscallDesc("truncate", truncateFunc), + /* 77 */ SyscallDesc("ftruncate", ftruncateFunc), /* 78 */ SyscallDesc("getdents", unimplementedFunc), /* 79 */ SyscallDesc("getcwd", unimplementedFunc), /* 80 */ SyscallDesc("chdir", unimplementedFunc), @@ -602,8 +602,8 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 89 */ SyscallDesc("readdir", unimplementedFunc), /* 90 */ SyscallDesc("mmap", unimplementedFunc), /* 91 */ SyscallDesc("munmap", munmapFunc), - /* 92 */ SyscallDesc("truncate", unimplementedFunc), - /* 93 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 92 */ SyscallDesc("truncate", truncateFunc), + /* 93 */ SyscallDesc("ftruncate", ftruncateFunc), /* 94 */ SyscallDesc("fchmod", unimplementedFunc), /* 95 */ SyscallDesc("fchown", unimplementedFunc), /* 96 */ SyscallDesc("getpriority", unimplementedFunc), @@ -703,8 +703,8 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 190 */ SyscallDesc("vfork", unimplementedFunc), /* 191 */ SyscallDesc("ugetrlimit", unimplementedFunc), /* 192 */ SyscallDesc("mmap2", mmapFunc), - /* 193 */ SyscallDesc("truncate64", unimplementedFunc), - /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc), + /* 193 */ SyscallDesc("truncate64", truncate64Func), + /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func), /* 195 */ SyscallDesc("stat64", stat64Func), /* 196 */ SyscallDesc("lstat64", unimplementedFunc), /* 197 */ SyscallDesc("fstat64", fstat64Func), From b2067840a6ad7e70495ad4dc6c74bf080e68133f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 14:19:06 -0400 Subject: [PATCH 069/160] X86: Implement the X86 sse2 haddpd instruction This patch implements the haddpd instruction. It fixes the problem in the previous version (pointed out by Gabe Black) where an incorrect result would happen if you issue the instruction with the same argument twice, i.e. "haddpd %xmm0,%xmm0" This instruction is used by many spec2k benchmarks. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 +- .../arithmetic/horizontal_addition.py | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 27aabaccc8..5512f417c4 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -707,7 +707,7 @@ } // operand size (0x66) 0x1: decode OPCODE_OP_BOTTOM3 { - 0x4: WarnUnimpl::haddpd_Vo_Wo(); + 0x4: HADDPD(Vo,Wo); 0x5: WarnUnimpl::hsubpd_Vo_Wo(); 0x6: WarnUnimpl::movd_Ed_Vd(); 0x7: MOVDQA(Wo,Vo); diff --git a/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py b/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py index 8b307d3da7..adf7650b9d 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py @@ -55,5 +55,25 @@ microcode = ''' # HADDPS -# HADDPD + +def macroop HADDPD_XMM_XMM { + maddf ufp1, xmmh , xmml, size=8, ext=1 + maddf xmmh, xmmlm, xmmhm, size=8, ext=1 + movfp xmml, ufp1 +}; + +def macroop HADDPD_XMM_M { + ldfp ufp1, seg, sib, disp, dataSize=8 + ldfp ufp2, seg, sib, "DISPLACEMENT+8", dataSize=8 + maddf xmml, xmmh, xmml, size=8, ext=1 + maddf xmmh, ufp1, ufp2, size=8, ext=1 +}; + +def macroop HADDPD_XMM_P { + rdip t7 + ldfp ufp1, seg, riprel, disp, dataSize=8 + ldfp ufp2, seg, riprel, "DISPLACEMENT+8", dataSize=8 + maddf xmml, xmmh, xmml, size=8, ext=1 + maddf xmmh, ufp1, ufp2, size=8, ext=1 +}; ''' From 5873ec2238e521f34f7e70e6aa1b35a611225d80 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 15:52:33 -0400 Subject: [PATCH 070/160] X86: Implement movd_Vo_Edp on X86 This patch implements the movd_Vo_Edp series of instructions. It addresses various concerns by Gabe Black about which file the instruction belonged in, as well as supporting REX prefixed instructions properly. This instruction is needed for some of the spec2k benchmarks, most notably bzip2. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 4 +-- .../general_purpose/data_transfer/move.py | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 5512f417c4..d52dfb26e9 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -615,7 +615,7 @@ 0x3: PACKSSDW(Vo,Wo); 0x4: PUNPCKLQDQ(Vo,Wq); 0x5: PUNPCKHQDQ(Vo,Wq); - 0x6: WarnUnimpl::movd_Vo_Ed(); + 0x6: MOVD(Vo,Edp); 0x7: MOVDQA(Vo,Wo); } default: UD2(); @@ -709,7 +709,7 @@ 0x1: decode OPCODE_OP_BOTTOM3 { 0x4: HADDPD(Vo,Wo); 0x5: WarnUnimpl::hsubpd_Vo_Wo(); - 0x6: WarnUnimpl::movd_Ed_Vd(); + 0x6: MOVD(Edp,Vd); 0x7: MOVDQA(Wo,Vo); default: UD2(); } diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 7ccdca6c34..7aee3fec1a 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -355,6 +355,36 @@ def macroop MOVNTI_P_R { rdip t7 st reg, seg, riprel, disp }; + +def macroop MOVD_XMM_R { + mov2fp xmml, regm, srcSize=dsz, destSize=dsz + lfpimm xmmh, 0 +}; + +def macroop MOVD_XMM_M { + ldfp xmml, seg, sib, disp, dataSize=dsz + lfpimm xmmh, 0 +}; + +def macroop MOVD_XMM_P { + rdip t7 + ldfp xmml, seg, riprel, disp, dataSize=dsz + lfpimm xmmh, 0 +}; + +def macroop MOVD_R_XMM { + mov2int reg, xmml, size=dsz +}; + +def macroop MOVD_M_XMM { + stfp xmml, seg, sib, disp, dataSize=dsz +}; + +def macroop MOVD_P_XMM { + rdip t7 + stfp xmml, seg, riprel, disp, dataSize=dsz +}; + ''' #let {{ # class MOVD(Inst): From a12557439ba0297fefb558b34ecc761d2bc34017 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 12:49:37 -0400 Subject: [PATCH 071/160] X86: Add support for x86 psrldq and pslldq instructions These are complicated instructions and the micro-code might be suboptimal. This has been tested with some small sample programs (attached) The psrldq instruction is needed by various spec2k programs. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 4 +- .../integer/shift/left_logical_shift.py | 40 ++++++++++++++++++- .../integer/shift/right_logical_shift.py | 38 +++++++++++++++++- 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index d52dfb26e9..288c5e5a86 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -673,9 +673,9 @@ //0x3: group14_pshimq(); 0x3: decode MODRM_REG { 0x2: PSRLQ(VRo,Ib); - 0x3: WarnUnimpl::psrldq_VRo_Ib(); + 0x3: PSRLDQ(VRo,Ib); 0x6: PSLLQ(VRo,Ib); - 0x7: WarnUnimpl::pslldq_VRo_Ib(); + 0x7: PSLLDQ(VRo,Ib); default: UD2(); } 0x4: PCMPEQB(Vo,Wo); diff --git a/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py b/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py index 617033bc03..c13c7064c3 100644 --- a/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py +++ b/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py @@ -122,5 +122,43 @@ def macroop PSLLQ_XMM_I { mslli xmml, xmml, imm, size=8, ext=0 mslli xmmh, xmmh, imm, size=8, ext=0 }; + +def macroop PSLLDQ_XMM_I { + + limm t2, 8 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("pslldq_less_8"), flags=(nCECF,) + + # Greater than 8 + + limm t2, 16 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("pslldq_less_16"), flags=(nCECF,) + + # Greater than 16 + + lfpimm xmml, 0 + lfpimm xmmh, 0 + br label("pslldq_end") + +pslldq_less_16: + + # Between 8 and 16 + + mslli xmmh, xmml, "(IMMEDIATE-8)<<3", size=8, ext=0 + lfpimm xmml, 0 + br label("pslldq_end") + +pslldq_less_8: + + # Less than 8 + + msrli ufp1, xmml, "(8-IMMEDIATE) << 3", size=8, ext=0 + mslli xmmh, xmmh, "IMMEDIATE << 3", size=8, ext=0 + mslli xmml, xmml, "IMMEDIATE << 3", size=8, ext=0 + mor xmmh, xmmh, ufp1 + +pslldq_end: + fault "NoFault" +}; ''' -# PSLLDQ diff --git a/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py b/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py index c904eaf50f..61efe1a5dd 100644 --- a/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py +++ b/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py @@ -122,5 +122,41 @@ def macroop PSRLQ_XMM_I { msrli xmml, xmml, imm, size=8, ext=0 msrli xmmh, xmmh, imm, size=8, ext=0 }; + +def macroop PSRLDQ_XMM_I { + limm t2, 8 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("psrldq_less_8"), flags=(nCECF,) + # Greater than 8 + + limm t2, 16 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("psrldq_less_16"), flags=(nCECF,) + + # Greater than 16 + + lfpimm xmml, 0 + lfpimm xmmh, 0 + br label("psrldq_end") + +psrldq_less_16: + + # Between 8 and 16 + + msrli xmml, xmmh, "(IMMEDIATE-8)<<3", size=8, ext=0 + lfpimm xmmh, 0 + br label("psrldq_end") + +psrldq_less_8: + + # Less than 8 + + mslli ufp1, xmmh, "(8-IMMEDIATE) << 3", size=8, ext=0 + msrli xmml, xmml, "IMMEDIATE << 3", size=8, ext=0 + msrli xmmh, xmmh, "IMMEDIATE << 3", size=8, ext=0 + mor xmml, xmml, ufp1 + +psrldq_end: + fault "NoFault" +}; ''' -# PSRLDQ From 9b0a747dd41d3383769be1cd737733902875a528 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 4 Nov 2009 00:19:15 -0500 Subject: [PATCH 072/160] X86: Hook up time syscall on X86 This has been tested and verified that it works. --- src/arch/x86/linux/syscalls.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 2a7fd8d4ea..6a659108fd 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -432,7 +432,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 198 */ SyscallDesc("lremovexattr", unimplementedFunc), /* 199 */ SyscallDesc("fremovexattr", unimplementedFunc), /* 200 */ SyscallDesc("tkill", unimplementedFunc), - /* 201 */ SyscallDesc("time", unimplementedFunc), + /* 201 */ SyscallDesc("time", timeFunc), /* 202 */ SyscallDesc("futex", ignoreFunc), /* 203 */ SyscallDesc("sched_setaffinity", unimplementedFunc), /* 204 */ SyscallDesc("sched_getaffinity", unimplementedFunc), @@ -523,7 +523,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 10 */ SyscallDesc("unlink", unimplementedFunc), /* 11 */ SyscallDesc("execve", unimplementedFunc), /* 12 */ SyscallDesc("chdir", unimplementedFunc), - /* 13 */ SyscallDesc("time", unimplementedFunc), + /* 13 */ SyscallDesc("time", timeFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 16 */ SyscallDesc("lchown", unimplementedFunc), From a1042db29098da395d0de96c652c41904feb425a Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 4 Nov 2009 00:47:12 -0500 Subject: [PATCH 073/160] X86: Enable x86_64 vsyscall support 64-bit vsyscall is different than 32-bit. There are only two syscalls, time and gettimeofday. On a real system, there is complicated code that implements these without entering the kernel. That would be complicated to implement in m5. Instead we just place code that calls the regular syscalls (this is how tools such as valgrind handle this case). This is needed for the perlbmk spec2k benchmark. --- src/arch/x86/process.cc | 24 ++++++++++++++++++++++++ src/arch/x86/process.hh | 10 ++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index f7b3ce24ae..7cc889d7cc 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -139,6 +139,12 @@ X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params, int _numSyscallDescs) : X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs) { + + vsyscallPage.base = 0xffffffffff600000ULL; + vsyscallPage.size = VMPageSize; + vsyscallPage.vtimeOffset = 0x400; + vsyscallPage.vgettimeofdayOffset = 0x410; + // Set up stack. On X86_64 Linux, stack goes from the top of memory // downward, less the hole for the kernel address space plus one page // for undertermined purposes. @@ -205,6 +211,24 @@ X86_64LiveProcess::startup() argsInit(sizeof(uint64_t), VMPageSize); + // Set up the vsyscall page for this process. + pTable->allocate(vsyscallPage.base, vsyscallPage.size); + uint8_t vtimeBlob[] = { + 0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00, // mov $0xc9,%rax + 0x0f,0x05, // syscall + 0xc3 // retq + }; + initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset, + vtimeBlob, sizeof(vtimeBlob)); + + uint8_t vgettimeofdayBlob[] = { + 0x48,0xc7,0xc0,0x60,0x00,0x00,0x00, // mov $0x60,%rax + 0x0f,0x05, // syscall + 0xc3 // retq + }; + initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vgettimeofdayOffset, + vgettimeofdayBlob, sizeof(vgettimeofdayBlob)); + for (int i = 0; i < contextIds.size(); i++) { ThreadContext * tc = system->getThreadContext(contextIds[i]); diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index 4d031bd5a3..3ad2abe08b 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -101,6 +101,16 @@ namespace X86ISA X86_64LiveProcess(LiveProcessParams *params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs); + class VSyscallPage + { + public: + Addr base; + Addr size; + Addr vtimeOffset; + Addr vgettimeofdayOffset; + }; + VSyscallPage vsyscallPage; + public: void argsInit(int intSize, int pageSize); void startup(); From 934ba5265e9296d2ab4b6c83b780e6cec81463ec Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Wed, 4 Nov 2009 14:23:24 -0800 Subject: [PATCH 074/160] stats: update memtest-ruby I don't know if the new stats are right or not, but we've been too long with a useless regression so I'm just going to update them. --- .../ref/alpha/linux/memtest-ruby/ruby.stats | 938 +++++++++--------- .../ref/alpha/linux/memtest-ruby/simerr | 146 +-- .../ref/alpha/linux/memtest-ruby/simout | 10 +- .../ref/alpha/linux/memtest-ruby/stats.txt | 38 +- 4 files changed, 572 insertions(+), 560 deletions(-) diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats index 9cdd67a6e8..28a2e20959 100644 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats @@ -12,7 +12,7 @@ RubySystem config: memory_size_bits: 30 DMA_Controller config: DMAController_0 version: 0 - buffer_size: 32 + buffer_size: 0 dma_sequencer: DMASequencer_0 number_of_TBEs: 256 recycle_latency: 10 @@ -20,7 +20,7 @@ DMA_Controller config: DMAController_0 transitions_per_cycle: 32 Directory_Controller config: DirectoryController_0 version: 0 - buffer_size: 32 + buffer_size: 0 directory_latency: 6 directory_name: DirectoryMemory_0 dma_select_low_bit: 6 @@ -31,7 +31,7 @@ Directory_Controller config: DirectoryController_0 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_0 version: 0 - buffer_size: 32 + buffer_size: 0 cache: l1u_0 cache_response_latency: 12 issue_latency: 2 @@ -41,7 +41,7 @@ L1Cache_Controller config: L1CacheController_0 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_1 version: 1 - buffer_size: 32 + buffer_size: 0 cache: l1u_1 cache_response_latency: 12 issue_latency: 2 @@ -51,7 +51,7 @@ L1Cache_Controller config: L1CacheController_1 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_2 version: 2 - buffer_size: 32 + buffer_size: 0 cache: l1u_2 cache_response_latency: 12 issue_latency: 2 @@ -61,7 +61,7 @@ L1Cache_Controller config: L1CacheController_2 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_3 version: 3 - buffer_size: 32 + buffer_size: 0 cache: l1u_3 cache_response_latency: 12 issue_latency: 2 @@ -71,7 +71,7 @@ L1Cache_Controller config: L1CacheController_3 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_4 version: 4 - buffer_size: 32 + buffer_size: 0 cache: l1u_4 cache_response_latency: 12 issue_latency: 2 @@ -81,7 +81,7 @@ L1Cache_Controller config: L1CacheController_4 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_5 version: 5 - buffer_size: 32 + buffer_size: 0 cache: l1u_5 cache_response_latency: 12 issue_latency: 2 @@ -91,7 +91,7 @@ L1Cache_Controller config: L1CacheController_5 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_6 version: 6 - buffer_size: 32 + buffer_size: 0 cache: l1u_6 cache_response_latency: 12 issue_latency: 2 @@ -101,7 +101,7 @@ L1Cache_Controller config: L1CacheController_6 transitions_per_cycle: 32 L1Cache_Controller config: L1CacheController_7 version: 7 - buffer_size: 32 + buffer_size: 0 cache: l1u_7 cache_response_latency: 12 issue_latency: 2 @@ -261,6 +261,10 @@ virtual_net_2: active, ordered virtual_net_3: inactive virtual_net_4: active, ordered virtual_net_5: active, ordered +virtual_net_6: inactive +virtual_net_7: inactive +virtual_net_8: inactive +virtual_net_9: inactive --- Begin Topology Print --- @@ -386,34 +390,34 @@ periodic_stats_period: 1000000 ================ End RubySystem Configuration Print ================ -Real time: Aug/11/2009 14:40:39 +Real time: Nov/03/2009 14:55:53 Profiler Stats -------------- -Elapsed_time_in_seconds: 3281 -Elapsed_time_in_minutes: 54.6833 -Elapsed_time_in_hours: 0.911389 -Elapsed_time_in_days: 0.0379745 +Elapsed_time_in_seconds: 892 +Elapsed_time_in_minutes: 14.8667 +Elapsed_time_in_hours: 0.247778 +Elapsed_time_in_days: 0.0103241 -Virtual_time_in_seconds: 2972.6 -Virtual_time_in_minutes: 49.5433 -Virtual_time_in_hours: 0.825722 -Virtual_time_in_days: 0.0344051 +Virtual_time_in_seconds: 889.79 +Virtual_time_in_minutes: 14.8298 +Virtual_time_in_hours: 0.247164 +Virtual_time_in_days: 0.0102985 -Ruby_current_time: 31749699 +Ruby_current_time: 31693011 Ruby_start_time: 1 -Ruby_cycles: 31749698 +Ruby_cycles: 31693010 -mbytes_resident: 151.695 -mbytes_total: 151.898 -resident_ratio: 0.998688 +mbytes_resident: 153.086 +mbytes_total: 1466.18 +resident_ratio: 0.104414 Total_misses: 0 total_misses: 0 [ 0 0 0 0 0 0 0 0 ] user_misses: 0 [ 0 0 0 0 0 0 0 0 ] supervisor_misses: 0 [ 0 0 0 0 0 0 0 0 ] -ruby_cycles_executed: 253997592 [ 31749699 31749699 31749699 31749699 31749699 31749699 31749699 31749699 ] +ruby_cycles_executed: 253544088 [ 31693011 31693011 31693011 31693011 31693011 31693011 31693011 31693011 ] transactions_started: 0 [ 0 0 0 0 0 0 0 0 ] transactions_ended: 0 [ 0 0 0 0 0 0 0 0 ] @@ -422,40 +426,40 @@ misses_per_transaction: 0 [ 0 0 0 0 0 0 0 0 ] Memory control MemoryControl_0: - memory_total_requests: 1384962 - memory_reads: 692528 - memory_writes: 692278 - memory_refreshes: 66146 - memory_total_request_delays: 423608080 - memory_delays_per_request: 305.863 - memory_delays_in_input_queue: 89056027 - memory_delays_behind_head_of_bank_queue: 254719145 - memory_delays_stalled_at_head_of_bank_queue: 79832908 - memory_stalls_for_bank_busy: 12075653 + memory_total_requests: 1382929 + memory_reads: 691503 + memory_writes: 691242 + memory_refreshes: 66028 + memory_total_request_delays: 424685881 + memory_delays_per_request: 307.092 + memory_delays_in_input_queue: 89365268 + memory_delays_behind_head_of_bank_queue: 255462545 + memory_delays_stalled_at_head_of_bank_queue: 79858068 + memory_stalls_for_bank_busy: 12071979 memory_stalls_for_random_busy: 0 - memory_stalls_for_anti_starvation: 24439291 - memory_stalls_for_arbitration: 15511923 - memory_stalls_for_bus: 20392505 + memory_stalls_for_anti_starvation: 24463399 + memory_stalls_for_arbitration: 15522067 + memory_stalls_for_bus: 20396836 memory_stalls_for_tfaw: 0 - memory_stalls_for_read_write_turnaround: 5977752 - memory_stalls_for_read_read_turnaround: 1435784 - accesses_per_bank: 43368 43904 43706 43665 43508 43366 43384 43354 43590 43325 43301 43542 43264 43288 43218 43319 43219 43118 43315 43079 43237 43057 43107 43328 43242 42939 43225 42922 42943 43105 42885 43139 + memory_stalls_for_read_write_turnaround: 5970102 + memory_stalls_for_read_read_turnaround: 1433685 + accesses_per_bank: 43013 43694 43739 43577 43477 43549 43400 43520 43342 43265 43265 43165 43087 43280 43291 43090 42980 42992 43280 43172 42991 43123 43177 43217 43344 43024 43173 42922 42657 42936 42917 43270 Busy Controller Counts: -L1Cache-0:0 L1Cache-1:0 L1Cache-2:1 L1Cache-3:0 L1Cache-4:0 L1Cache-5:1 L1Cache-6:0 L1Cache-7:1 +L1Cache-0:0 L1Cache-1:0 L1Cache-2:0 L1Cache-3:0 L1Cache-4:0 L1Cache-5:1 L1Cache-6:1 L1Cache-7:0 Directory-0:0 DMA-0:0 Busy Bank Count:0 -sequencer_requests_outstanding: [binsize: 1 max: 16 count: 746700 average: 11.7618 | standard deviation: 3.42904 | 0 1181 3107 5986 10114 16132 24128 33710 44657 55083 64138 69988 72441 71345 68309 64111 142270 ] +sequencer_requests_outstanding: [binsize: 1 max: 16 count: 745817 average: 11.8049 | standard deviation: 3.3976 | 0 1090 2744 5398 9406 15430 23546 33441 44604 54944 64080 70066 72710 71820 68564 65093 142881 ] All Non-Zero Cycle Demand Cache Accesses ---------------------------------------- -miss_latency: [binsize: 128 max: 21029 count: 746603 average: 3851.15 | standard deviation: 2350.44 | 21624 2037 3827 6735 8744 8494 7742 8727 10265 12114 13603 13888 12189 13262 16379 16977 16477 16214 17513 17457 16778 18444 19486 16712 16151 17669 18008 15987 15648 16356 15357 14058 14375 15390 13471 12148 12876 13458 11534 10630 11403 10961 9404 9160 10054 8956 7565 7967 8417 7419 6268 6810 6747 5598 5106 5611 5301 4304 4253 4461 4055 3421 3498 3461 3011 2534 2720 2664 2157 1912 2028 1911 1498 1441 1519 1315 1010 1086 1032 937 690 761 739 551 470 511 494 399 364 334 302 239 267 269 203 196 181 186 121 145 135 120 82 83 82 77 58 67 56 72 50 39 33 27 28 31 32 22 29 30 17 15 24 9 20 12 8 10 23 5 12 6 9 6 8 8 9 5 1 3 3 4 1 2 2 4 1 1 5 3 2 0 3 0 2 3 0 0 0 1 1 0 0 0 1 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 0 0 0 ] -miss_latency_2: [binsize: 128 max: 20539 count: 484935 average: 3851.68 | standard deviation: 2350.63 | 13904 1332 2494 4329 5749 5607 5063 5713 6766 7842 8848 9053 7883 8567 10537 10962 10638 10565 11405 11350 10806 12022 12693 10961 10540 11414 11604 10373 10192 10631 9965 9143 9337 9992 8755 7843 8355 8762 7428 6918 7435 7161 6157 5981 6496 5813 4849 5172 5493 4828 4049 4428 4328 3623 3316 3646 3442 2848 2798 2919 2659 2252 2225 2229 1937 1638 1781 1744 1433 1232 1308 1290 987 935 1010 866 664 696 662 603 432 499 463 350 290 332 316 246 240 209 206 142 174 178 129 124 108 122 77 99 92 77 54 48 58 48 32 42 37 50 33 28 24 17 20 23 25 15 22 20 14 10 13 5 16 9 5 5 14 3 7 3 2 4 4 5 6 4 1 3 3 3 0 1 2 3 0 1 4 1 0 0 3 0 2 2 0 0 0 1 1 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 0 0 0 0 0 0 ] -miss_latency_3: [binsize: 128 max: 21029 count: 261668 average: 3850.17 | standard deviation: 2350.1 | 7720 705 1333 2406 2995 2887 2679 3014 3499 4272 4755 4835 4306 4695 5842 6015 5839 5649 6108 6107 5972 6422 6793 5751 5611 6255 6404 5614 5456 5725 5392 4915 5038 5398 4716 4305 4521 4696 4106 3712 3968 3800 3247 3179 3558 3143 2716 2795 2924 2591 2219 2382 2419 1975 1790 1965 1859 1456 1455 1542 1396 1169 1273 1232 1074 896 939 920 724 680 720 621 511 506 509 449 346 390 370 334 258 262 276 201 180 179 178 153 124 125 96 97 93 91 74 72 73 64 44 46 43 43 28 35 24 29 26 25 19 22 17 11 9 10 8 8 7 7 7 10 3 5 11 4 4 3 3 5 9 2 5 3 7 2 4 3 3 1 0 0 0 1 1 1 0 1 1 0 1 2 2 0 0 0 0 1 0 0 0 0 0 0 0 0 1 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 0 0 0 ] +miss_latency: [binsize: 128 max: 20699 count: 745717 average: 3865 | standard deviation: 2351.52 | 21754 2058 3346 6576 8668 8377 7613 8584 10100 11818 13663 13336 12389 13097 16379 17199 16086 16157 17043 17386 16626 18695 19215 16901 15943 17630 18236 16024 15652 16370 15646 14274 14424 15394 13703 11981 12957 13262 11516 10766 11366 11178 9497 9444 9929 9046 7835 7972 8271 7278 6362 6864 6580 5689 5240 5566 5224 4337 4206 4581 4050 3302 3393 3480 2968 2642 2730 2675 2196 2020 2139 1952 1510 1484 1488 1240 1021 1076 1110 871 774 775 735 600 545 491 542 356 366 385 321 272 258 246 231 160 191 163 144 116 138 123 95 82 90 73 47 56 70 54 50 36 38 34 32 33 29 26 8 19 23 20 12 16 18 13 15 7 7 11 11 3 15 4 12 6 7 10 8 4 1 5 5 3 3 4 3 0 0 2 1 1 0 2 0 1 1 2 0 0 0 1 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 0 0 0 0 0 0 ] +miss_latency_2: [binsize: 128 max: 20699 count: 485064 average: 3865.43 | standard deviation: 2349.44 | 14100 1323 2132 4283 5700 5430 4976 5577 6639 7727 8762 8690 7975 8507 10567 11178 10575 10466 11091 11329 10802 12188 12472 10976 10321 11551 11898 10321 10187 10655 10222 9350 9367 9968 8885 7759 8434 8727 7594 6995 7447 7302 6134 6111 6428 5954 5120 5195 5346 4711 4145 4468 4350 3682 3455 3602 3384 2814 2709 2987 2632 2198 2209 2285 1930 1707 1742 1703 1478 1304 1384 1271 977 984 932 792 643 722 716 595 501 484 477 379 343 324 345 219 229 259 204 176 169 153 139 105 126 110 91 71 94 78 67 57 65 44 35 33 41 39 29 26 26 22 18 18 15 21 6 12 13 14 5 9 11 12 7 5 4 5 10 1 11 4 6 5 6 6 7 2 0 4 2 3 3 3 2 0 0 2 1 1 0 1 0 0 0 1 0 0 0 1 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 0 0 0 0 0 ] +miss_latency_3: [binsize: 128 max: 20151 count: 260653 average: 3864.21 | standard deviation: 2355.37 | 7654 735 1214 2293 2968 2947 2637 3007 3461 4091 4901 4646 4414 4590 5812 6021 5511 5691 5952 6057 5824 6507 6743 5925 5622 6079 6338 5703 5465 5715 5424 4924 5057 5426 4818 4222 4523 4535 3922 3771 3919 3876 3363 3333 3501 3092 2715 2777 2925 2567 2217 2396 2230 2007 1785 1964 1840 1523 1497 1594 1418 1104 1184 1195 1038 935 988 972 718 716 755 681 533 500 556 448 378 354 394 276 273 291 258 221 202 167 197 137 137 126 117 96 89 93 92 55 65 53 53 45 44 45 28 25 25 29 12 23 29 15 21 10 12 12 14 15 14 5 2 7 10 6 7 7 7 1 8 2 3 6 1 2 4 0 6 1 1 4 1 2 1 1 3 0 0 1 1 0 0 0 0 0 0 1 0 1 1 1 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 0 0 0 0 0 0 0 0 0 0 ] All Non-Zero Cycle SW Prefetch Requests ------------------------------------ @@ -469,135 +473,139 @@ filter_action: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN Message Delayed Cycles ---------------------- -Total_delay_cycles: [binsize: 1 max: 34 count: 1493362 average: 0.00198612 | standard deviation: 0.174419 | 1493159 0 2 0 0 0 4 0 2 0 15 0 25 0 45 0 77 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] -Total_nonPF_delay_cycles: [binsize: 1 max: 34 count: 1493362 average: 0.00198612 | standard deviation: 0.174419 | 1493159 0 2 0 0 0 4 0 2 0 15 0 25 0 45 0 77 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] +Total_delay_cycles: [binsize: 1 max: 34 count: 1491601 average: 0.00196835 | standard deviation: 0.175086 | 1491404 1 1 0 1 0 1 0 1 3 7 3 18 8 36 19 42 20 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] +Total_nonPF_delay_cycles: [binsize: 1 max: 34 count: 1491601 average: 0.00196835 | standard deviation: 0.175086 | 1491404 1 1 0 1 0 1 0 1 3 7 3 18 8 36 19 42 20 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] virtual_network_0_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] - virtual_network_1_delay_cycles: [binsize: 1 max: 0 count: 746603 average: 0 | standard deviation: 0 | 746603 ] - virtual_network_2_delay_cycles: [binsize: 1 max: 34 count: 746759 average: 0.00397183 | standard deviation: 0.246637 | 746556 0 2 0 0 0 4 0 2 0 15 0 25 0 45 0 77 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] + virtual_network_1_delay_cycles: [binsize: 1 max: 0 count: 745717 average: 0 | standard deviation: 0 | 745717 ] + virtual_network_2_delay_cycles: [binsize: 1 max: 34 count: 745884 average: 0.00393627 | standard deviation: 0.247579 | 745687 1 1 0 1 0 1 0 1 3 7 3 18 8 36 19 42 20 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] virtual_network_3_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] virtual_network_4_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] virtual_network_5_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] + virtual_network_6_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] + virtual_network_7_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] + virtual_network_8_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] + virtual_network_9_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] Resource Usage -------------- page_size: 4096 -user_time: 2896 -system_time: 75 -page_reclaims: 38173 -page_faults: 1923 +user_time: 889 +system_time: 0 +page_reclaims: 39882 +page_faults: 0 swaps: 0 -block_inputs: 0 -block_outputs: 0 +block_inputs: 32 +block_outputs: 144 Network Stats ------------- switch_0_inlinks: 2 switch_0_outlinks: 2 -links_utilized_percent_switch_0: 0.0918637 - links_utilized_percent_switch_0_link_0: 0.0367355 bw: 640000 base_latency: 1 - links_utilized_percent_switch_0_link_1: 0.146992 bw: 160000 base_latency: 1 +links_utilized_percent_switch_0: 0.0919149 + links_utilized_percent_switch_0_link_0: 0.0367576 bw: 640000 base_latency: 1 + links_utilized_percent_switch_0_link_1: 0.147072 bw: 160000 base_latency: 1 - outgoing_messages_switch_0_link_0_Response_Data: 93305 6717960 [ 0 93305 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_0_Writeback_Control: 93328 746624 [ 0 0 93328 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_1_Control: 93321 746568 [ 93321 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_1_Data: 86792 6249024 [ 86792 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_1_Response_Data: 6549 471528 [ 0 6549 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_0_Response_Data: 93195 6710040 [ 0 93195 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_0_Writeback_Control: 93211 745688 [ 0 0 93211 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_1_Control: 93208 745664 [ 93208 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_1_Data: 86476 6226272 [ 86476 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_1_Response_Data: 6749 485928 [ 0 6749 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_1_inlinks: 2 switch_1_outlinks: 2 -links_utilized_percent_switch_1: 0.0918631 - links_utilized_percent_switch_1_link_0: 0.0367386 bw: 640000 base_latency: 1 - links_utilized_percent_switch_1_link_1: 0.146988 bw: 160000 base_latency: 1 +links_utilized_percent_switch_1: 0.0919746 + links_utilized_percent_switch_1_link_0: 0.0367803 bw: 640000 base_latency: 1 + links_utilized_percent_switch_1_link_1: 0.147169 bw: 160000 base_latency: 1 - outgoing_messages_switch_1_link_0_Response_Data: 93314 6718608 [ 0 93314 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_0_Writeback_Control: 93325 746600 [ 0 0 93325 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_1_Control: 93321 746568 [ 93321 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_1_Data: 86443 6223896 [ 86443 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_1_Response_Data: 6895 496440 [ 0 6895 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_1_link_0_Response_Data: 93252 6714144 [ 0 93252 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_1_link_0_Writeback_Control: 93276 746208 [ 0 0 93276 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_1_link_1_Control: 93262 746096 [ 93262 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_1_link_1_Data: 86505 6228360 [ 86505 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_1_link_1_Response_Data: 6782 488304 [ 0 6782 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_2_inlinks: 2 switch_2_outlinks: 2 -links_utilized_percent_switch_2: 0.0918489 - links_utilized_percent_switch_2_link_0: 0.0367347 bw: 640000 base_latency: 1 - links_utilized_percent_switch_2_link_1: 0.146963 bw: 160000 base_latency: 1 +links_utilized_percent_switch_2: 0.0919005 + links_utilized_percent_switch_2_link_0: 0.0367529 bw: 640000 base_latency: 1 + links_utilized_percent_switch_2_link_1: 0.147048 bw: 160000 base_latency: 1 - outgoing_messages_switch_2_link_0_Response_Data: 93304 6717888 [ 0 93304 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_0_Writeback_Control: 93317 746536 [ 0 0 93317 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_1_Control: 93309 746472 [ 93309 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_1_Data: 86441 6223752 [ 86441 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_1_Response_Data: 6881 495432 [ 0 6881 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_2_link_0_Response_Data: 93184 6709248 [ 0 93184 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_2_link_0_Writeback_Control: 93192 745536 [ 0 0 93192 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_2_link_1_Control: 93199 745592 [ 93199 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_2_link_1_Data: 86329 6215688 [ 86329 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_2_link_1_Response_Data: 6880 495360 [ 0 6880 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_3_inlinks: 2 switch_3_outlinks: 2 -links_utilized_percent_switch_3: 0.0918764 - links_utilized_percent_switch_3_link_0: 0.0367424 bw: 640000 base_latency: 1 - links_utilized_percent_switch_3_link_1: 0.14701 bw: 160000 base_latency: 1 +links_utilized_percent_switch_3: 0.0919481 + links_utilized_percent_switch_3_link_0: 0.0367693 bw: 640000 base_latency: 1 + links_utilized_percent_switch_3_link_1: 0.147127 bw: 160000 base_latency: 1 - outgoing_messages_switch_3_link_0_Response_Data: 93323 6719256 [ 0 93323 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_0_Writeback_Control: 93340 746720 [ 0 0 93340 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_1_Control: 93330 746640 [ 93330 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_1_Data: 86471 6225912 [ 86471 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_1_Response_Data: 6882 495504 [ 0 6882 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_3_link_0_Response_Data: 93224 6712128 [ 0 93224 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_3_link_0_Writeback_Control: 93249 745992 [ 0 0 93249 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_3_link_1_Control: 93230 745840 [ 93230 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_3_link_1_Data: 86495 6227640 [ 86495 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_3_link_1_Response_Data: 6766 487152 [ 0 6766 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_4_inlinks: 2 switch_4_outlinks: 2 -links_utilized_percent_switch_4: 0.091891 - links_utilized_percent_switch_4_link_0: 0.0367495 bw: 640000 base_latency: 1 - links_utilized_percent_switch_4_link_1: 0.147032 bw: 160000 base_latency: 1 +links_utilized_percent_switch_4: 0.0919309 + links_utilized_percent_switch_4_link_0: 0.0367621 bw: 640000 base_latency: 1 + links_utilized_percent_switch_4_link_1: 0.1471 bw: 160000 base_latency: 1 - outgoing_messages_switch_4_link_0_Response_Data: 93342 6720624 [ 0 93342 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_0_Writeback_Control: 93350 746800 [ 0 0 93350 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_1_Control: 93353 746824 [ 93353 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_1_Data: 86738 6245136 [ 86738 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_1_Response_Data: 6628 477216 [ 0 6628 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_4_link_0_Response_Data: 93206 6710832 [ 0 93206 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_4_link_0_Writeback_Control: 93228 745824 [ 0 0 93228 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_4_link_1_Control: 93219 745752 [ 93219 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_4_link_1_Data: 86285 6212520 [ 86285 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_4_link_1_Response_Data: 6958 500976 [ 0 6958 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_5_inlinks: 2 switch_5_outlinks: 2 -links_utilized_percent_switch_5: 0.0918769 - links_utilized_percent_switch_5_link_0: 0.0367404 bw: 640000 base_latency: 1 - links_utilized_percent_switch_5_link_1: 0.147013 bw: 160000 base_latency: 1 +links_utilized_percent_switch_5: 0.0919246 + links_utilized_percent_switch_5_link_0: 0.0367591 bw: 640000 base_latency: 1 + links_utilized_percent_switch_5_link_1: 0.14709 bw: 160000 base_latency: 1 - outgoing_messages_switch_5_link_0_Response_Data: 93317 6718824 [ 0 93317 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_0_Writeback_Control: 93344 746752 [ 0 0 93344 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_1_Control: 93331 746648 [ 93331 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_1_Data: 86620 6236640 [ 86620 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_1_Response_Data: 6735 484920 [ 0 6735 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_5_link_0_Response_Data: 93198 6710256 [ 0 93198 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_5_link_0_Writeback_Control: 93222 745776 [ 0 0 93222 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_5_link_1_Control: 93213 745704 [ 93213 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_5_link_1_Data: 86640 6238080 [ 86640 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_5_link_1_Response_Data: 6597 474984 [ 0 6597 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_6_inlinks: 2 switch_6_outlinks: 2 -links_utilized_percent_switch_6: 0.0919038 - links_utilized_percent_switch_6_link_0: 0.0367512 bw: 640000 base_latency: 1 - links_utilized_percent_switch_6_link_1: 0.147057 bw: 160000 base_latency: 1 +links_utilized_percent_switch_6: 0.0919589 + links_utilized_percent_switch_6_link_0: 0.036773 bw: 640000 base_latency: 1 + links_utilized_percent_switch_6_link_1: 0.147145 bw: 160000 base_latency: 1 - outgoing_messages_switch_6_link_0_Response_Data: 93344 6720768 [ 0 93344 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_0_Writeback_Control: 93375 747000 [ 0 0 93375 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_1_Control: 93353 746824 [ 93353 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_1_Data: 86552 6231744 [ 86552 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_1_Response_Data: 6831 491832 [ 0 6831 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_6_link_0_Response_Data: 93233 6712776 [ 0 93233 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_6_link_0_Writeback_Control: 93260 746080 [ 0 0 93260 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_6_link_1_Control: 93245 745960 [ 93245 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_6_link_1_Data: 86585 6234120 [ 86585 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_6_link_1_Response_Data: 6687 481464 [ 0 6687 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_7_inlinks: 2 switch_7_outlinks: 2 -links_utilized_percent_switch_7: 0.0919101 - links_utilized_percent_switch_7_link_0: 0.0367549 bw: 640000 base_latency: 1 - links_utilized_percent_switch_7_link_1: 0.147065 bw: 160000 base_latency: 1 +links_utilized_percent_switch_7: 0.0919419 + links_utilized_percent_switch_7_link_0: 0.0367696 bw: 640000 base_latency: 1 + links_utilized_percent_switch_7_link_1: 0.147114 bw: 160000 base_latency: 1 - outgoing_messages_switch_7_link_0_Response_Data: 93354 6721488 [ 0 93354 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_0_Writeback_Control: 93380 747040 [ 0 0 93380 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_1_Control: 93364 746912 [ 93364 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_1_Data: 86714 6243408 [ 86714 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_1_Response_Data: 6674 480528 [ 0 6674 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_7_link_0_Response_Data: 93225 6712200 [ 0 93225 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_7_link_0_Writeback_Control: 93246 745968 [ 0 0 93246 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_7_link_1_Control: 93231 745848 [ 93231 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_7_link_1_Data: 86453 6224616 [ 86453 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_7_link_1_Response_Data: 6799 489528 [ 0 6799 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_8_inlinks: 2 switch_8_outlinks: 2 -links_utilized_percent_switch_8: 0.687008 - links_utilized_percent_switch_8_link_0: 0.27487 bw: 640000 base_latency: 1 - links_utilized_percent_switch_8_link_1: 1.09915 bw: 160000 base_latency: 1 +links_utilized_percent_switch_8: 0.687242 + links_utilized_percent_switch_8_link_0: 0.274971 bw: 640000 base_latency: 1 + links_utilized_percent_switch_8_link_1: 1.09951 bw: 160000 base_latency: 1 - outgoing_messages_switch_8_link_0_Control: 746682 5973456 [ 746682 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_8_link_0_Data: 692771 49879512 [ 692771 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_8_link_1_Response_Data: 692528 49862016 [ 0 692528 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_8_link_1_Writeback_Control: 746759 5974072 [ 0 0 746759 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_0_Control: 745807 5966456 [ 745807 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_0_Data: 691768 49807296 [ 691768 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_1_Response_Data: 691499 49787928 [ 0 691499 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_1_Writeback_Control: 745884 5967072 [ 0 0 745884 0 0 0 0 0 0 0 ] base_latency: 1 switch_9_inlinks: 2 switch_9_outlinks: 2 @@ -608,148 +616,148 @@ links_utilized_percent_switch_9: 0 switch_10_inlinks: 10 switch_10_outlinks: 10 -links_utilized_percent_switch_10: 0.227527 - links_utilized_percent_switch_10_link_0: 0.146942 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_1: 0.146954 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_2: 0.146939 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_3: 0.146969 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_4: 0.146998 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_5: 0.146962 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_6: 0.147005 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_7: 0.14702 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_8: 1.09948 bw: 160000 base_latency: 1 +links_utilized_percent_switch_10: 0.227638 + links_utilized_percent_switch_10_link_0: 0.14703 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_1: 0.147121 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_2: 0.147012 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_3: 0.147077 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_4: 0.147049 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_5: 0.147036 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_6: 0.147092 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_7: 0.147078 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_8: 1.09988 bw: 160000 base_latency: 1 links_utilized_percent_switch_10_link_9: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_10_link_0_Response_Data: 93305 6717960 [ 0 93305 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_0_Writeback_Control: 93328 746624 [ 0 0 93328 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_1_Response_Data: 93314 6718608 [ 0 93314 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_1_Writeback_Control: 93325 746600 [ 0 0 93325 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_2_Response_Data: 93304 6717888 [ 0 93304 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_2_Writeback_Control: 93317 746536 [ 0 0 93317 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_3_Response_Data: 93323 6719256 [ 0 93323 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_3_Writeback_Control: 93340 746720 [ 0 0 93340 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_4_Response_Data: 93342 6720624 [ 0 93342 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_4_Writeback_Control: 93350 746800 [ 0 0 93350 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_5_Response_Data: 93317 6718824 [ 0 93317 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_5_Writeback_Control: 93344 746752 [ 0 0 93344 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_6_Response_Data: 93344 6720768 [ 0 93344 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_6_Writeback_Control: 93375 747000 [ 0 0 93375 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_7_Response_Data: 93354 6721488 [ 0 93354 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_7_Writeback_Control: 93380 747040 [ 0 0 93380 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_8_Control: 746682 5973456 [ 746682 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_8_Data: 692771 49879512 [ 692771 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_0_Response_Data: 93195 6710040 [ 0 93195 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_0_Writeback_Control: 93211 745688 [ 0 0 93211 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_1_Response_Data: 93252 6714144 [ 0 93252 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_1_Writeback_Control: 93276 746208 [ 0 0 93276 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_2_Response_Data: 93184 6709248 [ 0 93184 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_2_Writeback_Control: 93192 745536 [ 0 0 93192 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_3_Response_Data: 93224 6712128 [ 0 93224 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_3_Writeback_Control: 93249 745992 [ 0 0 93249 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_4_Response_Data: 93206 6710832 [ 0 93206 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_4_Writeback_Control: 93228 745824 [ 0 0 93228 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_5_Response_Data: 93198 6710256 [ 0 93198 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_5_Writeback_Control: 93222 745776 [ 0 0 93222 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_6_Response_Data: 93233 6712776 [ 0 93233 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_6_Writeback_Control: 93260 746080 [ 0 0 93260 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_7_Response_Data: 93225 6712200 [ 0 93225 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_7_Writeback_Control: 93246 745968 [ 0 0 93246 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_8_Control: 745807 5966456 [ 745807 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_8_Data: 691768 49807296 [ 691768 0 0 0 0 0 0 0 0 0 ] base_latency: 1 l1u_0 cache stats: - l1u_0_total_misses: 93321 - l1u_0_total_demand_misses: 93321 + l1u_0_total_misses: 93208 + l1u_0_total_demand_misses: 93208 l1u_0_total_prefetches: 0 l1u_0_total_sw_prefetches: 0 l1u_0_total_hw_prefetches: 0 l1u_0_misses_per_transaction: inf - l1u_0_request_type_LD: 65.0004% - l1u_0_request_type_ST: 34.9996% + l1u_0_request_type_LD: 65.0406% + l1u_0_request_type_ST: 34.9594% - l1u_0_access_mode_type_SupervisorMode: 93321 100% - l1u_0_request_size: [binsize: log2 max: 1 count: 93321 average: 1 | standard deviation: 0 | 0 93321 ] + l1u_0_access_mode_type_SupervisorMode: 93208 100% + l1u_0_request_size: [binsize: log2 max: 1 count: 93208 average: 1 | standard deviation: 0 | 0 93208 ] l1u_1 cache stats: - l1u_1_total_misses: 93321 - l1u_1_total_demand_misses: 93321 + l1u_1_total_misses: 93262 + l1u_1_total_demand_misses: 93262 l1u_1_total_prefetches: 0 l1u_1_total_sw_prefetches: 0 l1u_1_total_hw_prefetches: 0 l1u_1_misses_per_transaction: inf - l1u_1_request_type_LD: 65.1536% - l1u_1_request_type_ST: 34.8464% + l1u_1_request_type_LD: 65.1348% + l1u_1_request_type_ST: 34.8652% - l1u_1_access_mode_type_SupervisorMode: 93321 100% - l1u_1_request_size: [binsize: log2 max: 1 count: 93321 average: 1 | standard deviation: 0 | 0 93321 ] + l1u_1_access_mode_type_SupervisorMode: 93262 100% + l1u_1_request_size: [binsize: log2 max: 1 count: 93262 average: 1 | standard deviation: 0 | 0 93262 ] l1u_2 cache stats: - l1u_2_total_misses: 93309 - l1u_2_total_demand_misses: 93309 + l1u_2_total_misses: 93199 + l1u_2_total_demand_misses: 93199 l1u_2_total_prefetches: 0 l1u_2_total_sw_prefetches: 0 l1u_2_total_hw_prefetches: 0 l1u_2_misses_per_transaction: inf - l1u_2_request_type_LD: 65.0002% - l1u_2_request_type_ST: 34.9998% + l1u_2_request_type_LD: 65.0157% + l1u_2_request_type_ST: 34.9843% - l1u_2_access_mode_type_SupervisorMode: 93309 100% - l1u_2_request_size: [binsize: log2 max: 1 count: 93309 average: 1 | standard deviation: 0 | 0 93309 ] + l1u_2_access_mode_type_SupervisorMode: 93199 100% + l1u_2_request_size: [binsize: log2 max: 1 count: 93199 average: 1 | standard deviation: 0 | 0 93199 ] l1u_3 cache stats: - l1u_3_total_misses: 93330 - l1u_3_total_demand_misses: 93330 + l1u_3_total_misses: 93230 + l1u_3_total_demand_misses: 93230 l1u_3_total_prefetches: 0 l1u_3_total_sw_prefetches: 0 l1u_3_total_hw_prefetches: 0 l1u_3_misses_per_transaction: inf - l1u_3_request_type_LD: 64.663% - l1u_3_request_type_ST: 35.337% + l1u_3_request_type_LD: 65.0542% + l1u_3_request_type_ST: 34.9458% - l1u_3_access_mode_type_SupervisorMode: 93330 100% - l1u_3_request_size: [binsize: log2 max: 1 count: 93330 average: 1 | standard deviation: 0 | 0 93330 ] + l1u_3_access_mode_type_SupervisorMode: 93230 100% + l1u_3_request_size: [binsize: log2 max: 1 count: 93230 average: 1 | standard deviation: 0 | 0 93230 ] l1u_4 cache stats: - l1u_4_total_misses: 93353 - l1u_4_total_demand_misses: 93353 + l1u_4_total_misses: 93219 + l1u_4_total_demand_misses: 93219 l1u_4_total_prefetches: 0 l1u_4_total_sw_prefetches: 0 l1u_4_total_hw_prefetches: 0 l1u_4_misses_per_transaction: inf - l1u_4_request_type_LD: 65.2555% - l1u_4_request_type_ST: 34.7445% + l1u_4_request_type_LD: 65.2142% + l1u_4_request_type_ST: 34.7858% - l1u_4_access_mode_type_SupervisorMode: 93353 100% - l1u_4_request_size: [binsize: log2 max: 1 count: 93353 average: 1 | standard deviation: 0 | 0 93353 ] + l1u_4_access_mode_type_SupervisorMode: 93219 100% + l1u_4_request_size: [binsize: log2 max: 1 count: 93219 average: 1 | standard deviation: 0 | 0 93219 ] l1u_5 cache stats: - l1u_5_total_misses: 93331 - l1u_5_total_demand_misses: 93331 + l1u_5_total_misses: 93213 + l1u_5_total_demand_misses: 93213 l1u_5_total_prefetches: 0 l1u_5_total_sw_prefetches: 0 l1u_5_total_hw_prefetches: 0 l1u_5_misses_per_transaction: inf - l1u_5_request_type_LD: 64.7148% - l1u_5_request_type_ST: 35.2852% + l1u_5_request_type_LD: 64.8976% + l1u_5_request_type_ST: 35.1024% - l1u_5_access_mode_type_SupervisorMode: 93331 100% - l1u_5_request_size: [binsize: log2 max: 1 count: 93331 average: 1 | standard deviation: 0 | 0 93331 ] + l1u_5_access_mode_type_SupervisorMode: 93213 100% + l1u_5_request_size: [binsize: log2 max: 1 count: 93213 average: 1 | standard deviation: 0 | 0 93213 ] l1u_6 cache stats: - l1u_6_total_misses: 93353 - l1u_6_total_demand_misses: 93353 + l1u_6_total_misses: 93245 + l1u_6_total_demand_misses: 93245 l1u_6_total_prefetches: 0 l1u_6_total_sw_prefetches: 0 l1u_6_total_hw_prefetches: 0 l1u_6_misses_per_transaction: inf - l1u_6_request_type_LD: 64.916% - l1u_6_request_type_ST: 35.084% + l1u_6_request_type_LD: 65.033% + l1u_6_request_type_ST: 34.967% - l1u_6_access_mode_type_SupervisorMode: 93353 100% - l1u_6_request_size: [binsize: log2 max: 1 count: 93353 average: 1 | standard deviation: 0 | 0 93353 ] + l1u_6_access_mode_type_SupervisorMode: 93245 100% + l1u_6_request_size: [binsize: log2 max: 1 count: 93245 average: 1 | standard deviation: 0 | 0 93245 ] l1u_7 cache stats: - l1u_7_total_misses: 93364 - l1u_7_total_demand_misses: 93364 + l1u_7_total_misses: 93231 + l1u_7_total_demand_misses: 93231 l1u_7_total_prefetches: 0 l1u_7_total_sw_prefetches: 0 l1u_7_total_hw_prefetches: 0 l1u_7_misses_per_transaction: inf - l1u_7_request_type_LD: 64.9201% - l1u_7_request_type_ST: 35.0799% + l1u_7_request_type_LD: 64.9805% + l1u_7_request_type_ST: 35.0195% - l1u_7_access_mode_type_SupervisorMode: 93364 100% - l1u_7_request_size: [binsize: log2 max: 1 count: 93364 average: 1 | standard deviation: 0 | 0 93364 ] + l1u_7_access_mode_type_SupervisorMode: 93231 100% + l1u_7_request_size: [binsize: log2 max: 1 count: 93231 average: 1 | standard deviation: 0 | 0 93231 ] --- DMA 0 --- - Event Counts - @@ -768,24 +776,24 @@ BUSY_WR Ack 0 <-- --- Directory 0 --- - Event Counts - -GETX 7453001 +GETX 7494804 GETS 0 -PUTX 692359 -PUTX_NotOwner 411 +PUTX 691343 +PUTX_NotOwner 425 DMA_READ 0 DMA_WRITE 0 -Memory_Data 692528 -Memory_Ack 692273 +Memory_Data 691500 +Memory_Ack 691241 - Transitions - -I GETX 692603 +I GETX 691586 I PUTX_NotOwner 0 <-- I DMA_READ 0 <-- I DMA_WRITE 0 <-- -M GETX 54075 -M PUTX 692359 -M PUTX_NotOwner 411 +M GETX 54218 +M PUTX 691343 +M PUTX_NotOwner 425 M DMA_READ 0 <-- M DMA_WRITE 0 <-- @@ -795,23 +803,27 @@ M_DRD PUTX 0 <-- M_DWR GETX 0 <-- M_DWR PUTX 0 <-- +M_DWRI GETX 0 <-- M_DWRI Memory_Ack 0 <-- -IM GETX 3217979 +M_DRDI GETX 0 <-- +M_DRDI Memory_Ack 0 <-- + +IM GETX 3180524 IM GETS 0 <-- IM PUTX 0 <-- IM PUTX_NotOwner 0 <-- IM DMA_READ 0 <-- IM DMA_WRITE 0 <-- -IM Memory_Data 692528 +IM Memory_Data 691500 -MI GETX 3488344 +MI GETX 3568476 MI GETS 0 <-- MI PUTX 0 <-- MI PUTX_NotOwner 0 <-- MI DMA_READ 0 <-- MI DMA_WRITE 0 <-- -MI Memory_Ack 692273 +MI Memory_Ack 691241 ID GETX 0 <-- ID GETS 0 <-- @@ -831,289 +843,289 @@ ID_W Memory_Ack 0 <-- --- L1Cache 0 --- - Event Counts - -Load 60659 +Load 60623 Ifetch 0 -Store 32662 -Data 93305 -Fwd_GETX 6549 +Store 32585 +Data 93195 +Fwd_GETX 6749 Inv 0 -Replacement 93289 -Writeback_Ack 86728 -Writeback_Nack 51 +Replacement 93176 +Writeback_Ack 86414 +Writeback_Nack 48 - Transitions - -I Load 60659 +I Load 60623 I Ifetch 0 <-- -I Store 32662 +I Store 32585 I Inv 0 <-- -I Replacement 6497 +I Replacement 6700 -II Writeback_Nack 51 +II Writeback_Nack 48 M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6498 +M Fwd_GETX 6701 M Inv 0 <-- -M Replacement 86792 +M Replacement 86476 -MI Fwd_GETX 51 +MI Fwd_GETX 48 MI Inv 0 <-- -MI Writeback_Ack 86728 +MI Writeback_Ack 86414 -IS Data 60648 +IS Data 60616 -IM Data 32657 +IM Data 32579 --- L1Cache 1 --- - Event Counts - -Load 60802 +Load 60746 Ifetch 0 -Store 32519 -Data 93314 -Fwd_GETX 6895 +Store 32516 +Data 93252 +Fwd_GETX 6782 Inv 0 -Replacement 93289 -Writeback_Ack 86383 -Writeback_Nack 47 - - - Transitions - -I Load 60802 -I Ifetch 0 <-- -I Store 32519 -I Inv 0 <-- -I Replacement 6846 - -II Writeback_Nack 47 - -M Load 0 <-- -M Ifetch 0 <-- -M Store 0 <-- -M Fwd_GETX 6848 -M Inv 0 <-- -M Replacement 86443 - -MI Fwd_GETX 47 -MI Inv 0 <-- -MI Writeback_Ack 86383 - -IS Data 60797 - -IM Data 32517 - - --- L1Cache 2 --- - - Event Counts - -Load 60651 -Ifetch 0 -Store 32658 -Data 93304 -Fwd_GETX 6881 -Inv 0 -Replacement 93277 -Writeback_Ack 86393 -Writeback_Nack 43 - - - Transitions - -I Load 60651 -I Ifetch 0 <-- -I Store 32658 -I Inv 0 <-- -I Replacement 6836 - -II Writeback_Nack 43 - -M Load 0 <-- -M Ifetch 0 <-- -M Store 0 <-- -M Fwd_GETX 6838 -M Inv 0 <-- -M Replacement 86441 - -MI Fwd_GETX 43 -MI Inv 0 <-- -MI Writeback_Ack 86393 - -IS Data 60647 - -IM Data 32657 - - --- L1Cache 3 --- - - Event Counts - -Load 60350 -Ifetch 0 -Store 32980 -Data 93323 -Fwd_GETX 6882 -Inv 0 -Replacement 93298 -Writeback_Ack 86405 -Writeback_Nack 53 - - - Transitions - -I Load 60350 -I Ifetch 0 <-- -I Store 32980 -I Inv 0 <-- -I Replacement 6827 - -II Writeback_Nack 53 - -M Load 0 <-- -M Ifetch 0 <-- -M Store 0 <-- -M Fwd_GETX 6829 -M Inv 0 <-- -M Replacement 86471 - -MI Fwd_GETX 53 -MI Inv 0 <-- -MI Writeback_Ack 86405 - -IS Data 60347 - -IM Data 32976 - - --- L1Cache 4 --- - - Event Counts - -Load 60918 -Ifetch 0 -Store 32435 -Data 93342 -Fwd_GETX 6628 -Inv 0 -Replacement 93321 -Writeback_Ack 86677 -Writeback_Nack 45 - - - Transitions - -I Load 60918 -I Ifetch 0 <-- -I Store 32435 -I Inv 0 <-- -I Replacement 6583 - -II Writeback_Nack 45 - -M Load 0 <-- -M Ifetch 0 <-- -M Store 0 <-- -M Fwd_GETX 6583 -M Inv 0 <-- -M Replacement 86738 - -MI Fwd_GETX 45 -MI Inv 0 <-- -MI Writeback_Ack 86677 - -IS Data 60909 - -IM Data 32433 - - --- L1Cache 5 --- - - Event Counts - -Load 60399 -Ifetch 0 -Store 32932 -Data 93317 -Fwd_GETX 6735 -Inv 0 -Replacement 93299 -Writeback_Ack 86554 -Writeback_Nack 55 - - - Transitions - -I Load 60399 -I Ifetch 0 <-- -I Store 32932 -I Inv 0 <-- -I Replacement 6679 - -II Writeback_Nack 55 - -M Load 0 <-- -M Ifetch 0 <-- -M Store 0 <-- -M Fwd_GETX 6680 -M Inv 0 <-- -M Replacement 86620 - -MI Fwd_GETX 55 -MI Inv 0 <-- -MI Writeback_Ack 86554 - -IS Data 60389 - -IM Data 32928 - - --- L1Cache 6 --- - - Event Counts - -Load 60601 -Ifetch 0 -Store 32752 -Data 93344 -Fwd_GETX 6831 -Inv 0 -Replacement 93321 -Writeback_Ack 86483 -Writeback_Nack 61 - - - Transitions - -I Load 60601 -I Ifetch 0 <-- -I Store 32752 -I Inv 0 <-- -I Replacement 6769 - -II Writeback_Nack 61 - -M Load 0 <-- -M Ifetch 0 <-- -M Store 0 <-- -M Fwd_GETX 6770 -M Inv 0 <-- -M Replacement 86552 - -MI Fwd_GETX 61 -MI Inv 0 <-- -MI Writeback_Ack 86483 - -IS Data 60595 - -IM Data 32749 - - --- L1Cache 7 --- - - Event Counts - -Load 60612 -Ifetch 0 -Store 32752 -Data 93354 -Fwd_GETX 6674 -Inv 0 -Replacement 93332 -Writeback_Ack 86650 +Replacement 93230 +Writeback_Ack 86438 Writeback_Nack 56 - Transitions - -I Load 60612 +I Load 60746 I Ifetch 0 <-- -I Store 32752 +I Store 32516 I Inv 0 <-- -I Replacement 6618 +I Replacement 6725 II Writeback_Nack 56 M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6618 +M Fwd_GETX 6726 M Inv 0 <-- -M Replacement 86714 +M Replacement 86505 MI Fwd_GETX 56 MI Inv 0 <-- -MI Writeback_Ack 86650 +MI Writeback_Ack 86438 -IS Data 60603 +IS Data 60738 -IM Data 32751 +IM Data 32514 + + --- L1Cache 2 --- + - Event Counts - +Load 60594 +Ifetch 0 +Store 32605 +Data 93184 +Fwd_GETX 6880 +Inv 0 +Replacement 93167 +Writeback_Ack 86271 +Writeback_Nack 41 + + - Transitions - +I Load 60594 +I Ifetch 0 <-- +I Store 32605 +I Inv 0 <-- +I Replacement 6838 + +II Writeback_Nack 41 + +M Load 0 <-- +M Ifetch 0 <-- +M Store 0 <-- +M Fwd_GETX 6839 +M Inv 0 <-- +M Replacement 86329 + +MI Fwd_GETX 41 +MI Inv 0 <-- +MI Writeback_Ack 86271 + +IS Data 60583 + +IM Data 32601 + + --- L1Cache 3 --- + - Event Counts - +Load 60650 +Ifetch 0 +Store 32580 +Data 93224 +Fwd_GETX 6766 +Inv 0 +Replacement 93198 +Writeback_Ack 86421 +Writeback_Nack 62 + + - Transitions - +I Load 60650 +I Ifetch 0 <-- +I Store 32580 +I Inv 0 <-- +I Replacement 6703 + +II Writeback_Nack 62 + +M Load 0 <-- +M Ifetch 0 <-- +M Store 0 <-- +M Fwd_GETX 6704 +M Inv 0 <-- +M Replacement 86495 + +MI Fwd_GETX 62 +MI Inv 0 <-- +MI Writeback_Ack 86421 + +IS Data 60647 + +IM Data 32577 + + --- L1Cache 4 --- + - Event Counts - +Load 60792 +Ifetch 0 +Store 32427 +Data 93206 +Fwd_GETX 6958 +Inv 0 +Replacement 93187 +Writeback_Ack 86214 +Writeback_Nack 56 + + - Transitions - +I Load 60792 +I Ifetch 0 <-- +I Store 32427 +I Inv 0 <-- +I Replacement 6902 + +II Writeback_Nack 56 + +M Load 0 <-- +M Ifetch 0 <-- +M Store 0 <-- +M Fwd_GETX 6902 +M Inv 0 <-- +M Replacement 86285 + +MI Fwd_GETX 56 +MI Inv 0 <-- +MI Writeback_Ack 86214 + +IS Data 60783 + +IM Data 32423 + + --- L1Cache 5 --- + - Event Counts - +Load 60493 +Ifetch 0 +Store 32720 +Data 93198 +Fwd_GETX 6597 +Inv 0 +Replacement 93181 +Writeback_Ack 86569 +Writeback_Nack 56 + + - Transitions - +I Load 60493 +I Ifetch 0 <-- +I Store 32720 +I Inv 0 <-- +I Replacement 6541 + +II Writeback_Nack 56 + +M Load 0 <-- +M Ifetch 0 <-- +M Store 0 <-- +M Fwd_GETX 6541 +M Inv 0 <-- +M Replacement 86640 + +MI Fwd_GETX 56 +MI Inv 0 <-- +MI Writeback_Ack 86569 + +IS Data 60486 + +IM Data 32712 + + --- L1Cache 6 --- + - Event Counts - +Load 60640 +Ifetch 0 +Store 32605 +Data 93233 +Fwd_GETX 6687 +Inv 0 +Replacement 93213 +Writeback_Ack 86519 +Writeback_Nack 54 + + - Transitions - +I Load 60640 +I Ifetch 0 <-- +I Store 32605 +I Inv 0 <-- +I Replacement 6628 + +II Writeback_Nack 54 + +M Load 0 <-- +M Ifetch 0 <-- +M Store 0 <-- +M Fwd_GETX 6633 +M Inv 0 <-- +M Replacement 86585 + +MI Fwd_GETX 54 +MI Inv 0 <-- +MI Writeback_Ack 86519 + +IS Data 60634 + +IM Data 32599 + + --- L1Cache 7 --- + - Event Counts - +Load 60582 +Ifetch 0 +Store 32649 +Data 93225 +Fwd_GETX 6799 +Inv 0 +Replacement 93199 +Writeback_Ack 86395 +Writeback_Nack 52 + + - Transitions - +I Load 60582 +I Ifetch 0 <-- +I Store 32649 +I Inv 0 <-- +I Replacement 6746 + +II Writeback_Nack 52 + +M Load 0 <-- +M Ifetch 0 <-- +M Store 0 <-- +M Fwd_GETX 6747 +M Inv 0 <-- +M Replacement 86453 + +MI Fwd_GETX 52 +MI Inv 0 <-- +MI Writeback_Ack 86395 + +IS Data 60577 + +IM Data 32648 diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr index af27693393..5a5c8990a0 100755 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr @@ -1,76 +1,76 @@ ["-r", "tests/configs/../../src/mem/ruby/config/MI_example-homogeneous.rb", "-p", "8", "-m", "1", "-s", "1024"] print config: 1 -system.cpu4: completed 10000 read accesses @3654068 -system.cpu1: completed 10000 read accesses @3658672 -system.cpu6: completed 10000 read accesses @3667702 -system.cpu0: completed 10000 read accesses @3693712 -system.cpu2: completed 10000 read accesses @3695692 -system.cpu7: completed 10000 read accesses @3702934 -system.cpu3: completed 10000 read accesses @3713843 -system.cpu5: completed 10000 read accesses @3747976 -system.cpu4: completed 20000 read accesses @6783252 -system.cpu6: completed 20000 read accesses @6788574 -system.cpu1: completed 20000 read accesses @6811444 -system.cpu2: completed 20000 read accesses @6811575 -system.cpu7: completed 20000 read accesses @6823208 -system.cpu3: completed 20000 read accesses @6833412 -system.cpu0: completed 20000 read accesses @6842332 -system.cpu5: completed 20000 read accesses @6892128 -system.cpu4: completed 30000 read accesses @9900552 -system.cpu6: completed 30000 read accesses @9919466 -system.cpu7: completed 30000 read accesses @9934195 -system.cpu3: completed 30000 read accesses @9940524 -system.cpu2: completed 30000 read accesses @9940526 -system.cpu0: completed 30000 read accesses @9949032 -system.cpu1: completed 30000 read accesses @10008962 -system.cpu5: completed 30000 read accesses @10013847 -system.cpu0: completed 40000 read accesses @12997824 -system.cpu3: completed 40000 read accesses @13026659 -system.cpu4: completed 40000 read accesses @13029141 -system.cpu6: completed 40000 read accesses @13053052 -system.cpu7: completed 40000 read accesses @13057445 -system.cpu2: completed 40000 read accesses @13075320 -system.cpu5: completed 40000 read accesses @13152513 -system.cpu1: completed 40000 read accesses @13163064 -system.cpu3: completed 50000 read accesses @16170822 -system.cpu0: completed 50000 read accesses @16183660 -system.cpu4: completed 50000 read accesses @16197183 -system.cpu6: completed 50000 read accesses @16212971 -system.cpu7: completed 50000 read accesses @16214970 -system.cpu5: completed 50000 read accesses @16230286 -system.cpu2: completed 50000 read accesses @16247930 -system.cpu1: completed 50000 read accesses @16329114 -system.cpu3: completed 60000 read accesses @19270542 -system.cpu0: completed 60000 read accesses @19311899 -system.cpu6: completed 60000 read accesses @19330724 -system.cpu4: completed 60000 read accesses @19371866 -system.cpu5: completed 60000 read accesses @19382898 -system.cpu7: completed 60000 read accesses @19384231 -system.cpu2: completed 60000 read accesses @19408394 -system.cpu1: completed 60000 read accesses @19459020 -system.cpu3: completed 70000 read accesses @22372299 -system.cpu6: completed 70000 read accesses @22442853 -system.cpu4: completed 70000 read accesses @22471794 -system.cpu0: completed 70000 read accesses @22486932 -system.cpu7: completed 70000 read accesses @22490492 -system.cpu5: completed 70000 read accesses @22527204 -system.cpu2: completed 70000 read accesses @22582036 -system.cpu1: completed 70000 read accesses @22588150 -system.cpu3: completed 80000 read accesses @25508231 -system.cpu6: completed 80000 read accesses @25562794 -system.cpu5: completed 80000 read accesses @25572200 -system.cpu0: completed 80000 read accesses @25620392 -system.cpu7: completed 80000 read accesses @25639710 -system.cpu4: completed 80000 read accesses @25649778 -system.cpu1: completed 80000 read accesses @25686718 -system.cpu2: completed 80000 read accesses @25733199 -system.cpu3: completed 90000 read accesses @28604804 -system.cpu6: completed 90000 read accesses @28707428 -system.cpu5: completed 90000 read accesses @28713115 -system.cpu0: completed 90000 read accesses @28743912 -system.cpu4: completed 90000 read accesses @28780814 -system.cpu7: completed 90000 read accesses @28781814 -system.cpu1: completed 90000 read accesses @28787396 -system.cpu2: completed 90000 read accesses @28868162 -system.cpu3: completed 100000 read accesses @31749698 +system.cpu4: completed 10000 read accesses @3675185 +system.cpu2: completed 10000 read accesses @3684370 +system.cpu1: completed 10000 read accesses @3684384 +system.cpu5: completed 10000 read accesses @3692230 +system.cpu7: completed 10000 read accesses @3697989 +system.cpu3: completed 10000 read accesses @3700408 +system.cpu0: completed 10000 read accesses @3740018 +system.cpu6: completed 10000 read accesses @3740090 +system.cpu4: completed 20000 read accesses @6800644 +system.cpu5: completed 20000 read accesses @6817332 +system.cpu1: completed 20000 read accesses @6845862 +system.cpu7: completed 20000 read accesses @6846102 +system.cpu3: completed 20000 read accesses @6846189 +system.cpu6: completed 20000 read accesses @6869288 +system.cpu0: completed 20000 read accesses @6871457 +system.cpu2: completed 20000 read accesses @6873399 +system.cpu5: completed 30000 read accesses @9907427 +system.cpu1: completed 30000 read accesses @9942140 +system.cpu4: completed 30000 read accesses @9951770 +system.cpu3: completed 30000 read accesses @9955002 +system.cpu2: completed 30000 read accesses @9959638 +system.cpu7: completed 30000 read accesses @10014906 +system.cpu6: completed 30000 read accesses @10028154 +system.cpu0: completed 30000 read accesses @10058436 +system.cpu3: completed 40000 read accesses @13045316 +system.cpu5: completed 40000 read accesses @13050166 +system.cpu4: completed 40000 read accesses @13057566 +system.cpu6: completed 40000 read accesses @13079138 +system.cpu2: completed 40000 read accesses @13081014 +system.cpu1: completed 40000 read accesses @13142214 +system.cpu0: completed 40000 read accesses @13144987 +system.cpu7: completed 40000 read accesses @13150846 +system.cpu3: completed 50000 read accesses @16142041 +system.cpu5: completed 50000 read accesses @16172122 +system.cpu6: completed 50000 read accesses @16220230 +system.cpu2: completed 50000 read accesses @16227420 +system.cpu4: completed 50000 read accesses @16237330 +system.cpu0: completed 50000 read accesses @16246676 +system.cpu1: completed 50000 read accesses @16278708 +system.cpu7: completed 50000 read accesses @16279864 +system.cpu3: completed 60000 read accesses @19234712 +system.cpu0: completed 60000 read accesses @19348851 +system.cpu6: completed 60000 read accesses @19370476 +system.cpu4: completed 60000 read accesses @19371128 +system.cpu5: completed 60000 read accesses @19373426 +system.cpu2: completed 60000 read accesses @19377688 +system.cpu7: completed 60000 read accesses @19379274 +system.cpu1: completed 60000 read accesses @19415186 +system.cpu3: completed 70000 read accesses @22337696 +system.cpu0: completed 70000 read accesses @22429460 +system.cpu4: completed 70000 read accesses @22492782 +system.cpu6: completed 70000 read accesses @22501157 +system.cpu2: completed 70000 read accesses @22508620 +system.cpu7: completed 70000 read accesses @22510770 +system.cpu5: completed 70000 read accesses @22526762 +system.cpu1: completed 70000 read accesses @22535410 +system.cpu3: completed 80000 read accesses @25425072 +system.cpu0: completed 80000 read accesses @25533098 +system.cpu1: completed 80000 read accesses @25591166 +system.cpu7: completed 80000 read accesses @25605790 +system.cpu5: completed 80000 read accesses @25629716 +system.cpu6: completed 80000 read accesses @25648430 +system.cpu4: completed 80000 read accesses @25658464 +system.cpu2: completed 80000 read accesses @25694944 +system.cpu3: completed 90000 read accesses @28554280 +system.cpu1: completed 90000 read accesses @28698524 +system.cpu0: completed 90000 read accesses @28699664 +system.cpu7: completed 90000 read accesses @28703590 +system.cpu4: completed 90000 read accesses @28740026 +system.cpu5: completed 90000 read accesses @28744438 +system.cpu2: completed 90000 read accesses @28783998 +system.cpu6: completed 90000 read accesses @28784829 +system.cpu3: completed 100000 read accesses @31693010 hack: be nice to actually delete the event here diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout index 465be4e7d1..8b71905663 100755 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout @@ -5,11 +5,11 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 11 2009 13:41:17 -M5 revision be123e27612f+ 6494+ default tip -M5 started Aug 11 2009 13:45:58 -M5 executing on svvint01 +M5 compiled Nov 3 2009 14:40:57 +M5 revision 0e5037cecaf7 6707 default tip +M5 started Nov 3 2009 14:41:01 +M5 executing on phenom command line: build/ALPHA_SE/m5.fast -d build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby -re tests/run.py build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... -Exiting @ tick 31749698 because maximum number of loads reached +Exiting @ tick 31693010 because maximum number of loads reached diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt index db2f23ad96..977e6ebbe6 100644 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt @@ -1,34 +1,34 @@ ---------- Begin Simulation Statistics ---------- -host_mem_usage 1507496 # Number of bytes of host memory used -host_seconds 3280.71 # Real time elapsed on the host -host_tick_rate 9678 # Simulator tick rate (ticks/s) +host_mem_usage 1501368 # Number of bytes of host memory used +host_seconds 892.41 # Real time elapsed on the host +host_tick_rate 35514 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_seconds 0.000032 # Number of seconds simulated -sim_ticks 31749698 # Number of ticks simulated +sim_ticks 31693010 # Number of ticks simulated system.cpu0.num_copies 0 # number of copy accesses completed -system.cpu0.num_reads 99565 # number of read accesses completed -system.cpu0.num_writes 53743 # number of write accesses completed +system.cpu0.num_reads 99568 # number of read accesses completed +system.cpu0.num_writes 53636 # number of write accesses completed system.cpu1.num_copies 0 # number of copy accesses completed -system.cpu1.num_reads 99657 # number of read accesses completed -system.cpu1.num_writes 53715 # number of write accesses completed +system.cpu1.num_reads 99545 # number of read accesses completed +system.cpu1.num_writes 53439 # number of write accesses completed system.cpu2.num_copies 0 # number of copy accesses completed -system.cpu2.num_reads 99204 # number of read accesses completed -system.cpu2.num_writes 53874 # number of write accesses completed +system.cpu2.num_reads 99287 # number of read accesses completed +system.cpu2.num_writes 53468 # number of write accesses completed system.cpu3.num_copies 0 # number of copy accesses completed system.cpu3.num_reads 100000 # number of read accesses completed -system.cpu3.num_writes 53515 # number of write accesses completed +system.cpu3.num_writes 53560 # number of write accesses completed system.cpu4.num_copies 0 # number of copy accesses completed -system.cpu4.num_reads 99473 # number of read accesses completed -system.cpu4.num_writes 53442 # number of write accesses completed +system.cpu4.num_reads 99582 # number of read accesses completed +system.cpu4.num_writes 53929 # number of write accesses completed system.cpu5.num_copies 0 # number of copy accesses completed -system.cpu5.num_reads 99627 # number of read accesses completed -system.cpu5.num_writes 53511 # number of write accesses completed +system.cpu5.num_reads 99543 # number of read accesses completed +system.cpu5.num_writes 53703 # number of write accesses completed system.cpu6.num_copies 0 # number of copy accesses completed -system.cpu6.num_reads 99662 # number of read accesses completed -system.cpu6.num_writes 53565 # number of write accesses completed +system.cpu6.num_reads 99253 # number of read accesses completed +system.cpu6.num_writes 53497 # number of write accesses completed system.cpu7.num_copies 0 # number of copy accesses completed -system.cpu7.num_reads 99533 # number of read accesses completed -system.cpu7.num_writes 53739 # number of write accesses completed +system.cpu7.num_reads 99640 # number of read accesses completed +system.cpu7.num_writes 53676 # number of write accesses completed ---------- End Simulation Statistics ---------- From fbfe92b5b8f4bfe229632d6d34e8ecb4dc7c1b29 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Wed, 4 Nov 2009 14:23:25 -0800 Subject: [PATCH 075/160] o3: get rid of unused physmem pointer --- src/cpu/o3/cpu.cc | 1 - src/cpu/o3/cpu.hh | 3 --- src/cpu/o3/thread_context.hh | 3 --- 3 files changed, 7 deletions(-) diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index de1e242019..2a4e0176a6 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -200,7 +200,6 @@ FullO3CPU::FullO3CPU(DerivO3CPUParams *params) globalSeqNum(1), #if FULL_SYSTEM system(params->system), - physmem(system->physmem), #endif // FULL_SYSTEM drainCount(0), deferRegistration(params->defer_registration) diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 65170d8b2f..2ea9189834 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -669,9 +669,6 @@ class FullO3CPU : public BaseO3CPU #if FULL_SYSTEM /** Pointer to the system. */ System *system; - - /** Pointer to physical memory. */ - PhysicalMemory *physmem; #endif /** Event to call process() on once draining has completed. */ diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 695b3b91a6..78b2660146 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -91,9 +91,6 @@ class O3ThreadContext : public ThreadContext virtual System *getSystemPtr() { return cpu->system; } #if FULL_SYSTEM - /** Returns a pointer to physical memory. */ - virtual PhysicalMemory *getPhysMemPtr() { return cpu->physmem; } - /** Returns a pointer to this thread's kernel statistics. */ virtual TheISA::Kernel::Statistics *getKernelStats() { return thread->kernelStats; } From 2c5fe6f95e64a5a97d56cccc6b8b5417cdd981ae Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 4 Nov 2009 16:57:01 -0800 Subject: [PATCH 076/160] build: fix compile problems pointed out by gcc 4.4 --- src/arch/arm/insts/static_inst.cc | 9 ++--- src/arch/mips/dsp.cc | 4 ++- src/arch/x86/interrupts.cc | 2 +- src/arch/x86/isa.cc | 2 +- src/arch/x86/system.cc | 2 +- src/base/bigint.cc | 4 +-- src/base/bigint.hh | 5 +-- src/base/inet.cc | 1 + src/base/remote_gdb.cc | 1 + src/base/types.hh | 1 + src/cpu/inorder/resource.hh | 1 + src/cpu/inst_seq.hh | 2 ++ src/cpu/legiontrace.cc | 4 ++- src/dev/sparc/iob.cc | 14 ++++---- src/dev/x86/i82094aa.cc | 2 +- src/kern/linux/linux.cc | 1 + src/mem/physical.cc | 1 + src/mem/ruby/common/Address.hh | 2 +- src/mem/ruby/network/orion/power_utils.cc | 42 +++++++++++++---------- src/sim/eventq.hh | 2 +- src/sim/process.cc | 2 ++ src/sim/syscall_emul.cc | 3 +- 22 files changed, 64 insertions(+), 43 deletions(-) diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index df2d5de251..5181041d03 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -29,6 +29,7 @@ #include "arch/arm/insts/static_inst.hh" #include "base/condcodes.hh" +#include "base/cprintf.hh" #include "base/loader/symtab.hh" namespace ArmISA @@ -62,7 +63,7 @@ ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt, else return (base << (32 - shamt)) | (base >> shamt); default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } @@ -101,7 +102,7 @@ ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt, else return (base << (32 - shamt)) | (base >> shamt); default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } @@ -141,7 +142,7 @@ ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt, else return (base >> (shamt - 1)) & 1; default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } @@ -182,7 +183,7 @@ ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt, shamt = 32; return (base >> (shamt - 1)) & 1; default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc index 6e4f7afead..b8b02ae9e1 100755 --- a/src/arch/mips/dsp.cc +++ b/src/arch/mips/dsp.cc @@ -463,6 +463,8 @@ MipsISA::dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl) uint64_t b_values[SIMD_MAX_VALS]; uint64_t c_values[SIMD_MAX_VALS]; + memset(c_values, 0, sizeof(c_values)); + simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED); simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED); @@ -743,7 +745,7 @@ MipsISA::dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac, int nvals = SIMD_NVALS[fmt]; uint64_t a_values[SIMD_MAX_VALS]; uint64_t b_values[SIMD_MAX_VALS]; - int64_t temp[2]; + int64_t temp[2] = {0, 0}; uint32_t ouflag = 0; simdUnpack(a, a_values, fmt, SIGNED); diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 1b7933036a..1b83c66495 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -500,7 +500,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) InterruptCommandRegHigh high = regs[APIC_INTERRUPT_COMMAND_HIGH]; // Record that an IPI is being sent. low.deliveryStatus = 1; - TriggerIntMessage message; + TriggerIntMessage message = 0; message.destination = high.destination; message.vector = low.vector; message.deliveryMode = low.deliveryMode; diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc index 06a656efc0..47d24ed1e6 100644 --- a/src/arch/x86/isa.cc +++ b/src/arch/x86/isa.cc @@ -41,7 +41,7 @@ void ISA::updateHandyM5Reg(Efer efer, CR0 cr0, SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags) { - HandyM5Reg m5reg; + HandyM5Reg m5reg = 0; if (efer.lma) { m5reg.mode = LongMode; if (csAttr.longMode) diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc index 1594cc3752..31183f2f90 100644 --- a/src/arch/x86/system.cc +++ b/src/arch/x86/system.cc @@ -211,7 +211,7 @@ X86System::startup() numGDTEntries++; - SegSelector ds; + SegSelector ds = 0; ds.si = numGDTEntries - 1; tc->setMiscReg(MISCREG_DS, (MiscReg)ds); diff --git a/src/base/bigint.cc b/src/base/bigint.cc index ce9942c9ce..d741e1f7bb 100644 --- a/src/base/bigint.cc +++ b/src/base/bigint.cc @@ -28,10 +28,10 @@ * Authors: Gabe Black */ -#include "base/bigint.hh" - #include +#include "base/bigint.hh" + using namespace std; ostream & operator << (ostream & os, const Twin64_t & t) diff --git a/src/base/bigint.hh b/src/base/bigint.hh index d606842314..a4e8738d30 100644 --- a/src/base/bigint.hh +++ b/src/base/bigint.hh @@ -28,10 +28,11 @@ * Authors: Ali Saidi */ -#include "base/misc.hh" - #include +#include "base/misc.hh" +#include "base/types.hh" + #ifndef __BASE_BIGINT_HH__ #define __BASE_BIGINT_HH__ // Create a couple of large int types for atomic reads diff --git a/src/base/inet.cc b/src/base/inet.cc index 898a189ef6..1a280e9930 100644 --- a/src/base/inet.cc +++ b/src/base/inet.cc @@ -28,6 +28,7 @@ * Authors: Nathan Binkert */ +#include #include #include diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index c54379c23a..68747b3d1d 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -118,6 +118,7 @@ #include +#include #include #include diff --git a/src/base/types.hh b/src/base/types.hh index 1a6db9fbba..0c10fac64e 100644 --- a/src/base/types.hh +++ b/src/base/types.hh @@ -55,6 +55,7 @@ typedef int64_t Counter; * @note using an unsigned breaks the cache. */ typedef int64_t Tick; +typedef uint64_t UTick; const Tick MaxTick = LL(0x7fffffffffffffff); diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh index 7935e55170..605b7f690e 100644 --- a/src/cpu/inorder/resource.hh +++ b/src/cpu/inorder/resource.hh @@ -36,6 +36,7 @@ #include #include +#include "base/types.hh" #include "cpu/inst_seq.hh" #include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/pipeline_traits.hh" diff --git a/src/cpu/inst_seq.hh b/src/cpu/inst_seq.hh index 21e04ed251..b5feaf5849 100644 --- a/src/cpu/inst_seq.hh +++ b/src/cpu/inst_seq.hh @@ -32,6 +32,8 @@ #ifndef __STD_TYPES_HH__ #define __STD_TYPES_HH__ +#include "base/types.hh" + // inst sequence type, used to order instructions in the ready list, // if this rolls over the ready list order temporarily will get messed // up, but execution will continue and complete correctly diff --git a/src/cpu/legiontrace.cc b/src/cpu/legiontrace.cc index f1980c713b..1390d0807f 100644 --- a/src/cpu/legiontrace.cc +++ b/src/cpu/legiontrace.cc @@ -41,10 +41,12 @@ #error Legion tracing only works in full system! #endif -#include #include #include +#include +#include + #include "arch/sparc/predecoder.hh" #include "arch/sparc/registers.hh" #include "arch/sparc/utility.hh" diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc index 4543dd07b2..40f856d8af 100644 --- a/src/dev/sparc/iob.cc +++ b/src/dev/sparc/iob.cc @@ -90,20 +90,18 @@ void Iob::readIob(PacketPtr pkt) { Addr accessAddr = pkt->getAddr() - iobManAddr; - int index; - uint64_t data; if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) { - index = (accessAddr - IntManAddr) >> 3; - data = intMan[index].cpu << 8 | intMan[index].vector << 0; + int index = (accessAddr - IntManAddr) >> 3; + uint64_t data = intMan[index].cpu << 8 | intMan[index].vector << 0; pkt->set(data); return; } if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) { - index = (accessAddr - IntManAddr) >> 3; - data = intCtl[index].mask ? 1 << 2 : 0 | - intCtl[index].pend ? 1 << 0 : 0; + int index = (accessAddr - IntCtlAddr) >> 3; + uint64_t data = intCtl[index].mask ? 1 << 2 : 0 | + intCtl[index].pend ? 1 << 0 : 0; pkt->set(data); return; } @@ -199,7 +197,7 @@ Iob::writeIob(PacketPtr pkt) } if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) { - index = (accessAddr - IntManAddr) >> 3; + index = (accessAddr - IntCtlAddr) >> 3; data = pkt->get(); intCtl[index].mask = bits(data,2,2); if (bits(data,1,1)) diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc index ed936d0cb7..591fee6a4d 100644 --- a/src/dev/x86/i82094aa.cc +++ b/src/dev/x86/i82094aa.cc @@ -151,7 +151,7 @@ X86ISA::I82094AA::signalInterrupt(int line) DPRINTF(I82094AA, "Entry was masked.\n"); return; } else { - TriggerIntMessage message; + TriggerIntMessage message = 0; message.destination = entry.dest; if (entry.deliveryMode == DeliveryMode::ExtInt) { assert(extIntPic); diff --git a/src/kern/linux/linux.cc b/src/kern/linux/linux.cc index abe7c0b752..72f1832b8e 100644 --- a/src/kern/linux/linux.cc +++ b/src/kern/linux/linux.cc @@ -28,6 +28,7 @@ * Authors: Ali Saidi */ +#include #include #include "cpu/thread_context.hh" diff --git a/src/mem/physical.cc b/src/mem/physical.cc index be4086cd90..121a6e447d 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -36,6 +36,7 @@ #include #include +#include #include #include diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh index c48152354c..88cd2668a0 100644 --- a/src/mem/ruby/common/Address.hh +++ b/src/mem/ruby/common/Address.hh @@ -148,7 +148,7 @@ inline physical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive { physical_address_t mask; - assert(big >= small); + assert((unsigned)big >= (unsigned)small); if (big >= ADDRESS_WIDTH - 1) { return (m_address >> small); diff --git a/src/mem/ruby/network/orion/power_utils.cc b/src/mem/ruby/network/orion/power_utils.cc index bc69c3cc7f..358e13c6fc 100644 --- a/src/mem/ruby/network/orion/power_utils.cc +++ b/src/mem/ruby/network/orion/power_utils.cc @@ -30,6 +30,7 @@ #include #include +#include "base/types.hh" #include "mem/ruby/network/orion/parm_technology.hh" #include "mem/ruby/network/orion/power_utils.hh" @@ -39,11 +40,11 @@ static char h_tab[256] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; -static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long int new_val, unsigned long int mask ) +static uint32_t SIM_power_Hamming_slow( uint64_t old_val, uint64_t new_val, uint64_t mask ) { /* old slow code, I don't understand the new fast code though */ - /* unsigned long int dist; - unsigned Hamming = 0; + /* uint64_t dist; + uint32_t Hamming = 0; dist = ( old_val ^ new_val ) & mask; mask = (mask >> 1) + 1; @@ -58,7 +59,7 @@ static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long #define TWO(k) (BIGONE << (k)) #define CYCL(k) (BIGNONE/(1 + (TWO(TWO(k))))) #define BSUM(x,k) ((x)+=(x) >> TWO(k), (x) &= CYCL(k)) - unsigned long int x; + uint64_t x; x = (old_val ^ new_val) & mask; x = (x & CYCL(0)) + ((x>>TWO(0)) & CYCL(0)); @@ -74,7 +75,7 @@ static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long int SIM_power_init(void) { - unsigned i; + uint32_t i; /* initialize Hamming distance table */ for (i = 0; i < 256; i++) @@ -84,14 +85,16 @@ int SIM_power_init(void) } -/* assume unsigned long int is unsigned64_t */ -unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val, unsigned long int mask) + +uint32_t +SIM_power_Hamming(uint64_t old_val, uint64_t new_val, uint64_t mask) { - union { - unsigned long int x; - char id[8]; - } u; - unsigned rval; + union { + uint64_t x; + uint64_t id[8]; + } u; + + uint32_t rval; u.x = (old_val ^ new_val) & mask; @@ -108,10 +111,12 @@ unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val, } -unsigned SIM_power_Hamming_group(unsigned long int d1_new, unsigned long int d1_old, unsigned long int d2_new, unsigned long int d2_old, unsigned width, unsigned n_grp) +uint32_t +SIM_power_Hamming_group(uint64_t d1_new, uint64_t d1_old, uint64_t d2_new, + uint64_t d2_old, uint32_t width, uint32_t n_grp) { - unsigned rval = 0; - unsigned long int g1_new, g1_old, g2_new, g2_old, mask; + uint32_t rval = 0; + uint64_t g1_new, g1_old, g2_new, g2_old, mask; mask = HAMM_MASK(width); @@ -146,11 +151,12 @@ double logtwo(double x) return log10(x)/log10(2); } -unsigned SIM_power_logtwo(unsigned long int x) +uint32_t +SIM_power_logtwo(uint64_t x) { - unsigned rval = 0; + uint32_t rval = 0; - while (x >> rval && rval < sizeof(unsigned long int) << 3) rval++; + while (x >> rval && rval < sizeof(uint64_t) << 3) rval++; if (x == (BIGONE << rval - 1)) rval--; return rval; diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index 29efdeb6f0..92c38142c0 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -471,7 +471,7 @@ class EventWrapper : public Event inline void EventQueue::schedule(Event *event, Tick when) { - assert(when >= curTick); + assert((UTick)when >= (UTick)curTick); assert(!event->scheduled()); #ifdef EVENTQ_DEBUG assert((event->flags & Event::Initialized) == Event::Initialized); diff --git a/src/sim/process.cc b/src/sim/process.cc index e71d6441f9..343d2ad5a6 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -32,6 +32,8 @@ #include #include + +#include #include #include "arch/remote_gdb.hh" diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index cc8d99bcdc..7cffffcf1c 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -32,8 +32,9 @@ #include #include -#include +#include #include +#include #include "sim/syscall_emul.hh" #include "base/chunk_generator.hh" From 058ccfc7fe7be1b7b7124ecdd0d9d79fe4d6a86f Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 5 Nov 2009 11:11:05 -0800 Subject: [PATCH 077/160] slicc: whack some of Nate's leftover debug code --- src/mem/protocol/SConscript | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript index 425219580d..948fd6c1ae 100644 --- a/src/mem/protocol/SConscript +++ b/src/mem/protocol/SConscript @@ -72,9 +72,6 @@ def slicc_emitter(target, source, env): hh,cc = slicc.files() target.extend(sorted(hh)) target.extend(sorted(cc)) - f = file('/tmp/asdf', 'w') - for t in target: - print >>f, t return target, source def slicc_action(target, source, env): From 9098010e3fccf779786c7f0e1dfab9d522f72eb5 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 5 Nov 2009 11:11:06 -0800 Subject: [PATCH 078/160] slicc: tweak file enumeration for scons Right now .cc and .hh files are handled separately, but then they're just munged together at the end by scons, so it doesn't buy us anything. Might as well munge from the start since we'll eventually be adding generated Python files to the list too. --- src/mem/protocol/SConscript | 4 +--- src/mem/slicc/ast/DeclAST.py | 4 ++-- src/mem/slicc/ast/DeclListAST.py | 6 ++++-- src/mem/slicc/ast/EnumDeclAST.py | 8 ++++---- src/mem/slicc/ast/FuncDeclAST.py | 6 +++--- src/mem/slicc/ast/MachineAST.py | 18 +++++++++--------- src/mem/slicc/ast/TypeDeclAST.py | 7 +++---- src/mem/slicc/main.py | 10 +--------- src/mem/slicc/parser.py | 10 ++++------ 9 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript index 948fd6c1ae..cd9920d225 100644 --- a/src/mem/protocol/SConscript +++ b/src/mem/protocol/SConscript @@ -69,9 +69,7 @@ def slicc_emitter(target, source, env): for name in slicc.load(files, verbose=True): print " %s" % name - hh,cc = slicc.files() - target.extend(sorted(hh)) - target.extend(sorted(cc)) + target.extend(sorted(slicc.files())) return target, source def slicc_action(target, source, env): diff --git a/src/mem/slicc/ast/DeclAST.py b/src/mem/slicc/ast/DeclAST.py index 2303725a39..1adb313213 100644 --- a/src/mem/slicc/ast/DeclAST.py +++ b/src/mem/slicc/ast/DeclAST.py @@ -31,8 +31,8 @@ class DeclAST(AST): def __init__(self, slicc, pairs): super(DeclAST, self).__init__(slicc, pairs) - def files(self, hh, cc, parent=None): - pass + def files(self, parent=None): + return set() def findMachines(self): return diff --git a/src/mem/slicc/ast/DeclListAST.py b/src/mem/slicc/ast/DeclListAST.py index 42f98afc74..36c5200709 100644 --- a/src/mem/slicc/ast/DeclListAST.py +++ b/src/mem/slicc/ast/DeclListAST.py @@ -38,9 +38,11 @@ class DeclListAST(AST): def __repr__(self): return "[DeclListAST: %s]" % (', '.join(repr(d) for d in self.decls)) - def files(self, hh, cc, parent=None): + def files(self, parent=None): + s = set() for decl in self.decls: - decl.files(hh, cc, parent) + s |= decl.files(parent) + return s def generate(self): for decl in self.decls: diff --git a/src/mem/slicc/ast/EnumDeclAST.py b/src/mem/slicc/ast/EnumDeclAST.py index c16fc8a750..a20f4b7496 100644 --- a/src/mem/slicc/ast/EnumDeclAST.py +++ b/src/mem/slicc/ast/EnumDeclAST.py @@ -38,16 +38,16 @@ class EnumDeclAST(DeclAST): def __repr__(self): return "[EnumDecl: %s]" % (self.type_ast) - def files(self, hh, cc, parent=None): + def files(self, parent=None): if "external" in self: - return + return set() if parent: ident = "%s_%s" % (parent, self.type_ast.ident) else: ident = self.type_ast.ident - hh.add("%s.hh" % ident) - cc.add("%s.cc" % ident) + s = set(("%s.hh" % ident, "%s.cc" % ident)) + return s def generate(self): ident = str(self.type_ast) diff --git a/src/mem/slicc/ast/FuncDeclAST.py b/src/mem/slicc/ast/FuncDeclAST.py index 7ff3bf8a77..980804c2af 100644 --- a/src/mem/slicc/ast/FuncDeclAST.py +++ b/src/mem/slicc/ast/FuncDeclAST.py @@ -42,15 +42,15 @@ class FuncDeclAST(DeclAST): def __repr__(self): return "[FuncDecl: %s]" % self.ident - def files(self, hh, cc, parent=None): + def files(self, parent=None): if "external" in self or self.statements is None: - return + return set() if parent: ident = "%s_%s" % (parent, self.ident) else: ident = self.ident - cc.add("%s.cc" % ident) + return set(("%s.cc" % ident,)) def generate(self): types = [] diff --git a/src/mem/slicc/ast/MachineAST.py b/src/mem/slicc/ast/MachineAST.py index 8d48ccbf58..ee75b6d6af 100644 --- a/src/mem/slicc/ast/MachineAST.py +++ b/src/mem/slicc/ast/MachineAST.py @@ -40,16 +40,16 @@ class MachineAST(DeclAST): def __repr__(self): return "[Machine: %r]" % self.ident - def files(self, hh, cc, parent=None): - hh.add('%s_Controller.hh' % self.ident) - hh.add('%s_Profiler.hh' % self.ident) + def files(self, parent=None): + s = set(('%s_Controller.cc' % self.ident, + '%s_Controller.hh' % self.ident, + '%s_Profiler.cc' % self.ident, + '%s_Profiler.hh' % self.ident, + '%s_Transitions.cc' % self.ident, + '%s_Wakeup.cc' % self.ident)) - cc.add('%s_Controller.cc' % self.ident) - cc.add('%s_Profiler.cc' % self.ident) - cc.add('%s_Transitions.cc' % self.ident) - cc.add('%s_Wakeup.cc' % self.ident) - - self.decls.files(hh, cc, self.ident) + s |= self.decls.files(self.ident) + return s def generate(self): # Make a new frame diff --git a/src/mem/slicc/ast/TypeDeclAST.py b/src/mem/slicc/ast/TypeDeclAST.py index d2cc04eff5..ecdb5949b5 100644 --- a/src/mem/slicc/ast/TypeDeclAST.py +++ b/src/mem/slicc/ast/TypeDeclAST.py @@ -38,16 +38,15 @@ class TypeDeclAST(DeclAST): def __repr__(self): return "[TypeDecl: %r]" % (self.type_ast) - def files(self, hh, cc, parent=None): + def files(self, parent=None): if "external" in self: - return + return set() if parent: ident = "%s_%s" % (parent, self.type_ast.ident) else: ident = self.type_ast.ident - hh.add("%s.hh" % ident) - cc.add("%s.cc" % ident) + return set(("%s.hh" % ident, "%s.cc" % ident)) def generate(self): ident = str(self.type_ast) diff --git a/src/mem/slicc/main.py b/src/mem/slicc/main.py index 0bc2ef37a6..f8efcc323f 100644 --- a/src/mem/slicc/main.py +++ b/src/mem/slicc/main.py @@ -78,15 +78,7 @@ def main(args=None): output(" %s", filename) if opts.print_files: - hh, cc = slicc.files() - hh = sorted(hh) - cc = sorted(cc) - print 'Headers:' - for i in hh: - print ' %s' % i - - print 'Sources:' - for i in cc: + for i in sorted(slicc.files()): print ' %s' % i else: output("Generator pass 1...") diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py index 0e5ccc885c..6c3f456298 100644 --- a/src/mem/slicc/parser.py +++ b/src/mem/slicc/parser.py @@ -114,19 +114,17 @@ class SLICC(Grammar): self.symtab.writeHTMLFiles(code_path) def files(self): - cc = set([ + f = set([ 'ControllerFactory.cc', - 'MachineType.cc']) - - hh = set([ 'ControllerFactory.hh', + 'MachineType.cc', 'MachineType.hh', 'Types.hh' ]) for decl_list in self.decl_list_vec: - decl_list.files(hh, cc) + f |= decl_list.files() - return hh, cc + return f t_ignore = '\t ' From 5cf2e7ccf027a485c2e2eb9a60b70c3b45853f0c Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 4 Nov 2009 13:22:15 -0500 Subject: [PATCH 079/160] X86: Fix problem with movhps instruction This problem is like the one fixed with movhpd a few weeks ago. A +8 displacement is used to access memory when there should be none. This fix is needed for the perlbmk spec2k benchmark to run. --- .../insts/simd128/floating_point/data_transfer/move.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py index ffe084786b..86ac89adeb 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py @@ -168,22 +168,21 @@ def macroop MOVUPD_P_XMM { }; def macroop MOVHPS_XMM_M { - ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPS_XMM_P { rdip t7 - ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVHPS_M_XMM { - stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPS_P_XMM { rdip t7 - stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 - stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVHPD_XMM_M { From 18b21c1ecaf7858c592c56cf4c12ec8781f821ba Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 7 Nov 2009 22:34:33 -0800 Subject: [PATCH 080/160] ARM: Get rid of some unneeded register indexes. --- src/arch/arm/registers.hh | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 7f9b6b8282..07af32c1e7 100644 --- a/src/arch/arm/registers.hh +++ b/src/arch/arm/registers.hh @@ -77,7 +77,6 @@ const int ReturnAddressReg = 14; const int PCReg = 15; const int ZeroReg = NumIntArchRegs; -const int AddrReg = ZeroReg + 1; // Used to generate address for uops const int SyscallNumReg = ReturnValueReg; const int SyscallPseudoReturnReg = ReturnValueReg; @@ -116,35 +115,6 @@ enum FCSRFields { Cause_Field = 11 }; -enum MiscIntRegNums { - zero_reg = NumIntArchRegs, - addr_reg, - - rhi, - rlo, - - r8_fiq, /* FIQ mode register bank */ - r9_fiq, - r10_fiq, - r11_fiq, - r12_fiq, - - r13_fiq, /* FIQ mode SP and LR */ - r14_fiq, - - r13_irq, /* IRQ mode SP and LR */ - r14_irq, - - r13_svc, /* SVC mode SP and LR */ - r14_svc, - - r13_undef, /* UNDEF mode SP and LR */ - r14_undef, - - r13_abt, /* ABT mode SP and LR */ - r14_abt -}; - } // namespace ArmISA #endif From 4a454c4f47362bd6f842fe1919f959a672ab1bb4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 00:07:35 -0800 Subject: [PATCH 081/160] ARM: Set up an intregs.hh for ARM. Add constants for all the modes and registers, maps for aliasing, functions that use the maps and range check, and use a named constant instead of a magic number for the microcode register. --- src/arch/arm/intregs.hh | 326 ++++++++++++++++++++++++++ src/arch/arm/isa/formats/macromem.isa | 10 +- src/arch/arm/registers.hh | 14 +- 3 files changed, 339 insertions(+), 11 deletions(-) create mode 100644 src/arch/arm/intregs.hh diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh new file mode 100644 index 0000000000..191965c557 --- /dev/null +++ b/src/arch/arm/intregs.hh @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2009 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include + +#ifndef __ARCH_ARM_INTREGS_HH__ +#define __ARCH_ARM_INTREGS_HH__ + +namespace ArmISA +{ + +enum IntRegIndex +{ + /* All the unique register indices. */ + INTREG_R0, + INTREG_R1, + INTREG_R2, + INTREG_R3, + INTREG_R4, + INTREG_R5, + INTREG_R6, + INTREG_R7, + INTREG_R8, + INTREG_R9, + INTREG_R10, + INTREG_R11, + INTREG_R12, + INTREG_R13, + INTREG_SP = INTREG_R13, + INTREG_R14, + INTREG_LR = INTREG_R14, + INTREG_R15, + INTREG_PC = INTREG_R15, + + INTREG_R13_SVC, + INTREG_SP_SVC = INTREG_R13_SVC, + INTREG_R14_SVC, + INTREG_LR_SVC = INTREG_R14_SVC, + INTREG_R15_SVC = INTREG_R15, + + INTREG_R13_MON, + INTREG_SP_MON = INTREG_R13_MON, + INTREG_R14_MON, + INTREG_LR_MON = INTREG_R14_MON, + INTREG_R15_MON = INTREG_R15, + + INTREG_R13_ABT, + INTREG_SP_ABT = INTREG_R13_ABT, + INTREG_R14_ABT, + INTREG_LR_ABT = INTREG_R14_ABT, + INTREG_R15_ABT = INTREG_R15, + + INTREG_R13_UND, + INTREG_SP_UND = INTREG_R13_UND, + INTREG_R14_UND, + INTREG_LR_UND = INTREG_R14_UND, + INTREG_R15_UND = INTREG_R15, + + INTREG_R13_IRQ, + INTREG_SP_IRQ = INTREG_R13_IRQ, + INTREG_R14_IRQ, + INTREG_LR_IRQ = INTREG_R14_IRQ, + INTREG_R15_IRQ = INTREG_R15, + + INTREG_R8_FIQ, + INTREG_R9_FIQ, + INTREG_R10_FIQ, + INTREG_R11_FIQ, + INTREG_R12_FIQ, + INTREG_R13_FIQ, + INTREG_SP_FIQ = INTREG_R13_FIQ, + INTREG_R14_FIQ, + INTREG_LR_FIQ = INTREG_R14_FIQ, + INTREG_R15_FIQ = INTREG_R15, + + INTREG_ZERO, // Dummy zero reg since there has to be one. + INTREG_UREG0, + + NUM_INTREGS, + NUM_ARCH_INTREGS = INTREG_PC + 1, + + /* All the aliased indexes. */ + + /* USR mode */ + INTREG_R0_USR = INTREG_R0, + INTREG_R1_USR = INTREG_R1, + INTREG_R2_USR = INTREG_R2, + INTREG_R3_USR = INTREG_R3, + INTREG_R4_USR = INTREG_R4, + INTREG_R5_USR = INTREG_R5, + INTREG_R6_USR = INTREG_R6, + INTREG_R7_USR = INTREG_R7, + INTREG_R8_USR = INTREG_R8, + INTREG_R9_USR = INTREG_R9, + INTREG_R10_USR = INTREG_R10, + INTREG_R11_USR = INTREG_R11, + INTREG_R12_USR = INTREG_R12, + INTREG_R13_USR = INTREG_R13, + INTREG_SP_USR = INTREG_SP, + INTREG_R14_USR = INTREG_R14, + INTREG_LR_USR = INTREG_LR, + INTREG_R15_USR = INTREG_R15, + INTREG_PC_USR = INTREG_PC, + + /* SVC mode */ + INTREG_R0_SVC = INTREG_R0, + INTREG_R1_SVC = INTREG_R1, + INTREG_R2_SVC = INTREG_R2, + INTREG_R3_SVC = INTREG_R3, + INTREG_R4_SVC = INTREG_R4, + INTREG_R5_SVC = INTREG_R5, + INTREG_R6_SVC = INTREG_R6, + INTREG_R7_SVC = INTREG_R7, + INTREG_R8_SVC = INTREG_R8, + INTREG_R9_SVC = INTREG_R9, + INTREG_R10_SVC = INTREG_R10, + INTREG_R11_SVC = INTREG_R11, + INTREG_R12_SVC = INTREG_R12, + INTREG_PC_SVC = INTREG_PC, + + /* MON mode */ + INTREG_R0_MON = INTREG_R0, + INTREG_R1_MON = INTREG_R1, + INTREG_R2_MON = INTREG_R2, + INTREG_R3_MON = INTREG_R3, + INTREG_R4_MON = INTREG_R4, + INTREG_R5_MON = INTREG_R5, + INTREG_R6_MON = INTREG_R6, + INTREG_R7_MON = INTREG_R7, + INTREG_R8_MON = INTREG_R8, + INTREG_R9_MON = INTREG_R9, + INTREG_R10_MON = INTREG_R10, + INTREG_R11_MON = INTREG_R11, + INTREG_R12_MON = INTREG_R12, + INTREG_PC_MON = INTREG_PC, + + /* ABT mode */ + INTREG_R0_ABT = INTREG_R0, + INTREG_R1_ABT = INTREG_R1, + INTREG_R2_ABT = INTREG_R2, + INTREG_R3_ABT = INTREG_R3, + INTREG_R4_ABT = INTREG_R4, + INTREG_R5_ABT = INTREG_R5, + INTREG_R6_ABT = INTREG_R6, + INTREG_R7_ABT = INTREG_R7, + INTREG_R8_ABT = INTREG_R8, + INTREG_R9_ABT = INTREG_R9, + INTREG_R10_ABT = INTREG_R10, + INTREG_R11_ABT = INTREG_R11, + INTREG_R12_ABT = INTREG_R12, + INTREG_PC_ABT = INTREG_PC, + + /* UND mode */ + INTREG_R0_UND = INTREG_R0, + INTREG_R1_UND = INTREG_R1, + INTREG_R2_UND = INTREG_R2, + INTREG_R3_UND = INTREG_R3, + INTREG_R4_UND = INTREG_R4, + INTREG_R5_UND = INTREG_R5, + INTREG_R6_UND = INTREG_R6, + INTREG_R7_UND = INTREG_R7, + INTREG_R8_UND = INTREG_R8, + INTREG_R9_UND = INTREG_R9, + INTREG_R10_UND = INTREG_R10, + INTREG_R11_UND = INTREG_R11, + INTREG_R12_UND = INTREG_R12, + INTREG_PC_UND = INTREG_PC, + + /* IRQ mode */ + INTREG_R0_IRQ = INTREG_R0, + INTREG_R1_IRQ = INTREG_R1, + INTREG_R2_IRQ = INTREG_R2, + INTREG_R3_IRQ = INTREG_R3, + INTREG_R4_IRQ = INTREG_R4, + INTREG_R5_IRQ = INTREG_R5, + INTREG_R6_IRQ = INTREG_R6, + INTREG_R7_IRQ = INTREG_R7, + INTREG_R8_IRQ = INTREG_R8, + INTREG_R9_IRQ = INTREG_R9, + INTREG_R10_IRQ = INTREG_R10, + INTREG_R11_IRQ = INTREG_R11, + INTREG_R12_IRQ = INTREG_R12, + INTREG_PC_IRQ = INTREG_PC, + + /* FIQ mode */ + INTREG_R0_FIQ = INTREG_R0, + INTREG_R1_FIQ = INTREG_R1, + INTREG_R2_FIQ = INTREG_R2, + INTREG_R3_FIQ = INTREG_R3, + INTREG_R4_FIQ = INTREG_R4, + INTREG_R5_FIQ = INTREG_R5, + INTREG_R6_FIQ = INTREG_R6, + INTREG_R7_FIQ = INTREG_R7, + INTREG_PC_FIQ = INTREG_PC, +}; + +typedef IntRegIndex IntRegMap[NUM_ARCH_INTREGS]; + +const IntRegMap IntRegUsrMap = { + INTREG_R0_USR, INTREG_R1_USR, INTREG_R2_USR, INTREG_R3_USR, + INTREG_R4_USR, INTREG_R5_USR, INTREG_R6_USR, INTREG_R7_USR, + INTREG_R8_USR, INTREG_R9_USR, INTREG_R10_USR, INTREG_R11_USR, + INTREG_R12_USR, INTREG_R13_USR, INTREG_R14_USR, INTREG_R15_USR +}; + +static inline IntRegIndex +INTREG_USR(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegUsrMap[index]; +} + +const IntRegMap IntRegSvcMap = { + INTREG_R0_SVC, INTREG_R1_SVC, INTREG_R2_SVC, INTREG_R3_SVC, + INTREG_R4_SVC, INTREG_R5_SVC, INTREG_R6_SVC, INTREG_R7_SVC, + INTREG_R8_SVC, INTREG_R9_SVC, INTREG_R10_SVC, INTREG_R11_SVC, + INTREG_R12_SVC, INTREG_R13_SVC, INTREG_R14_SVC, INTREG_R15_SVC +}; + +static inline IntRegIndex +INTREG_SVC(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegSvcMap[index]; +} + +const IntRegMap IntRegMonMap = { + INTREG_R0_MON, INTREG_R1_MON, INTREG_R2_MON, INTREG_R3_MON, + INTREG_R4_MON, INTREG_R5_MON, INTREG_R6_MON, INTREG_R7_MON, + INTREG_R8_MON, INTREG_R9_MON, INTREG_R10_MON, INTREG_R11_MON, + INTREG_R12_MON, INTREG_R13_MON, INTREG_R14_MON, INTREG_R15_MON +}; + +static inline IntRegIndex +INTREG_MON(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegMonMap[index]; +} + +const IntRegMap IntRegAbtMap = { + INTREG_R0_ABT, INTREG_R1_ABT, INTREG_R2_ABT, INTREG_R3_ABT, + INTREG_R4_ABT, INTREG_R5_ABT, INTREG_R6_ABT, INTREG_R7_ABT, + INTREG_R8_ABT, INTREG_R9_ABT, INTREG_R10_ABT, INTREG_R11_ABT, + INTREG_R12_ABT, INTREG_R13_ABT, INTREG_R14_ABT, INTREG_R15_ABT +}; + +static inline IntRegIndex +INTREG_ABT(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegAbtMap[index]; +} + +const IntRegMap IntRegUndMap = { + INTREG_R0_UND, INTREG_R1_UND, INTREG_R2_UND, INTREG_R3_UND, + INTREG_R4_UND, INTREG_R5_UND, INTREG_R6_UND, INTREG_R7_UND, + INTREG_R8_UND, INTREG_R9_UND, INTREG_R10_UND, INTREG_R11_UND, + INTREG_R12_UND, INTREG_R13_UND, INTREG_R14_UND, INTREG_R15_UND +}; + +static inline IntRegIndex +INTREG_UND(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegUndMap[index]; +} + +const IntRegMap IntRegIrqMap = { + INTREG_R0_IRQ, INTREG_R1_IRQ, INTREG_R2_IRQ, INTREG_R3_IRQ, + INTREG_R4_IRQ, INTREG_R5_IRQ, INTREG_R6_IRQ, INTREG_R7_IRQ, + INTREG_R8_IRQ, INTREG_R9_IRQ, INTREG_R10_IRQ, INTREG_R11_IRQ, + INTREG_R12_IRQ, INTREG_R13_IRQ, INTREG_R14_IRQ, INTREG_R15_IRQ +}; + +static inline IntRegIndex +INTREG_IRQ(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegIrqMap[index]; +} + +const IntRegMap IntRegFiqMap = { + INTREG_R0_FIQ, INTREG_R1_FIQ, INTREG_R2_FIQ, INTREG_R3_FIQ, + INTREG_R4_FIQ, INTREG_R5_FIQ, INTREG_R6_FIQ, INTREG_R7_FIQ, + INTREG_R8_FIQ, INTREG_R9_FIQ, INTREG_R10_FIQ, INTREG_R11_FIQ, + INTREG_R12_FIQ, INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_R15_FIQ +}; + +static inline IntRegIndex +INTREG_FIQ(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegFiqMap[index]; +} + +} + +#endif diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 355a67ea9b..d978967ac2 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -213,9 +213,9 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) break; } - // Add 0 to Rn and stick it in Raddr (register 17). + // Add 0 to Rn and stick it in ureg0. // This is equivalent to a move. - microOps[0] = new MicroAddiUop(machInst, 17, RN, 0); + microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0); unsigned j = 0; for (int i = 1; i < ones+1; i++) { @@ -225,9 +225,11 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) regs_to_handle &= ~(1< Date: Sun, 8 Nov 2009 00:07:49 -0800 Subject: [PATCH 082/160] ARM: Implement the shadow registers using register flattening. --- src/arch/arm/isa.hh | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 9b21c03cd7..1ad5428e52 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -44,14 +44,44 @@ namespace ArmISA { protected: MiscReg miscRegs[NumMiscRegs]; + const IntRegIndex *intRegMap; + + void + updateRegMap(CPSR cpsr) + { + switch (cpsr.mode) { + case MODE_USER: + case MODE_SYSTEM: + intRegMap = IntRegUsrMap; + break; + case MODE_FIQ: + intRegMap = IntRegFiqMap; + break; + case MODE_IRQ: + intRegMap = IntRegIrqMap; + break; + case MODE_SVC: + intRegMap = IntRegSvcMap; + break; + case MODE_ABORT: + intRegMap = IntRegAbtMap; + break; + case MODE_UNDEFINED: + intRegMap = IntRegUndMap; + break; + default: + panic("Unrecognized mode setting in CPSR.\n"); + } + } public: void clear() { memset(miscRegs, 0, sizeof(miscRegs)); CPSR cpsr = 0; - cpsr.mode = MODE_USER; + cpsr.mode = MODE_SYSTEM; miscRegs[MISCREG_CPSR] = cpsr; + updateRegMap(cpsr); //XXX We need to initialize the rest of the state. } @@ -79,6 +109,9 @@ namespace ArmISA void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) { + if (misc_reg == MISCREG_CPSR) { + updateRegMap(val); + } assert(misc_reg < NumMiscRegs); miscRegs[misc_reg] = val; } @@ -86,7 +119,13 @@ namespace ArmISA int flattenIntIndex(int reg) { - return reg; + assert(reg >= 0); + if (reg < NUM_ARCH_INTREGS) { + return intRegMap[reg]; + } else { + assert(reg < NUM_INTREGS); + return reg; + } } int From 43e9209c218daf506b6c2580e689e297c48e8f48 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 00:54:32 -0800 Subject: [PATCH 083/160] ARM: Initialize processes in user mode. I accidentally left in a change to test using int registers in system mode. This change reverts that. --- src/arch/arm/isa.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 1ad5428e52..6341e6cd01 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -79,7 +79,7 @@ namespace ArmISA { memset(miscRegs, 0, sizeof(miscRegs)); CPSR cpsr = 0; - cpsr.mode = MODE_SYSTEM; + cpsr.mode = MODE_USER; miscRegs[MISCREG_CPSR] = cpsr; updateRegMap(cpsr); //XXX We need to initialize the rest of the state. From f63c260d89591d8d57274bb37aea51dc7c093b8f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 01:57:34 -0800 Subject: [PATCH 084/160] ARM: Get rid of the Raddr operand. --- src/arch/arm/isa/operands.isa | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index ac7427dad0..a4c404bd55 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -63,7 +63,6 @@ def operands {{ 'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite), 'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite), - 'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6), 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7), 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8), 'LR': ('IntReg', 'uw', '14', 'IsInteger', 9), From 78bd8fe44fe3398f361335d2feb59a8221cc52e8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 01:59:20 -0800 Subject: [PATCH 085/160] ARM: Add back in spots for Rhi and Rlo, and use a named constant for LR. --- src/arch/arm/intregs.hh | 2 ++ src/arch/arm/isa/operands.isa | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 191965c557..78ad39ee2a 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -102,6 +102,8 @@ enum IntRegIndex INTREG_ZERO, // Dummy zero reg since there has to be one. INTREG_UREG0, + INTREG_RHI, + INTREG_RLO, NUM_INTREGS, NUM_ARCH_INTREGS = INTREG_PC + 1, diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index a4c404bd55..4ac6790e54 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -63,9 +63,9 @@ def operands {{ 'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite), 'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite), - 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7), - 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8), - 'LR': ('IntReg', 'uw', '14', 'IsInteger', 9), + 'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7), + 'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8), + 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9), #Register fields for microops 'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite), From 3a3e8461511663a3154d0507ba1b0f52ea5366c5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 02:00:55 -0800 Subject: [PATCH 086/160] ARM: Get rid of NumInternalProcRegs. That constant is a carry over from Alpha and doesn't do anything in ARM. --- src/arch/arm/registers.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 04fd00f3a1..41bbf4e7f2 100644 --- a/src/arch/arm/registers.hh +++ b/src/arch/arm/registers.hh @@ -55,7 +55,6 @@ typedef uint64_t MiscReg; const int NumIntArchRegs = NUM_ARCH_INTREGS; const int NumFloatArchRegs = 16; const int NumFloatSpecialRegs = 5; -const int NumInternalProcRegs = 0; const int NumIntRegs = NUM_INTREGS; const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs; From d188821d3700ee42e01fc43c9ef17568991fb3ff Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 02:01:02 -0800 Subject: [PATCH 087/160] ARM: Add in more bits for the mon mode. --- src/arch/arm/isa.hh | 3 +++ src/arch/arm/miscregs.hh | 1 + src/arch/arm/types.hh | 1 + 3 files changed, 5 insertions(+) diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 6341e6cd01..f8359679b2 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -63,6 +63,9 @@ namespace ArmISA case MODE_SVC: intRegMap = IntRegSvcMap; break; + case MODE_MON: + intRegMap = IntRegMonMap; + break; case MODE_ABORT: intRegMap = IntRegAbtMap; break; diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 3180669de3..ba394d49c5 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -59,6 +59,7 @@ namespace ArmISA MISCREG_SPSR_FIQ, MISCREG_SPSR_IRQ, MISCREG_SPSR_SVC, + MISCREG_SPSR_MON, MISCREG_SPSR_UND, MISCREG_SPSR_ABT, MISCREG_FPSR, diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 2c4e1291c0..d5cc07eaf6 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -156,6 +156,7 @@ namespace ArmISA MODE_FIQ = 17, MODE_IRQ = 18, MODE_SVC = 19, + MODE_MON = 22, MODE_ABORT = 23, MODE_UNDEFINED = 27, MODE_SYSTEM = 31 From 48525f581c6233b8f7a8a872c5774d4e245f431c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 02:08:40 -0800 Subject: [PATCH 088/160] ARM: Split the condition codes out of the CPSR. This allows those bits to be renamed while allowing the other fields to control the behavior of the processor. --- src/arch/arm/intregs.hh | 1 + src/arch/arm/isa/decoder.isa | 20 +++++++++++++------- src/arch/arm/isa/formats/branch.isa | 4 ++-- src/arch/arm/isa/formats/fp.isa | 4 ++-- src/arch/arm/isa/formats/pred.isa | 28 ++++++++++++++-------------- src/arch/arm/isa/formats/util.isa | 6 ++++-- src/arch/arm/isa/operands.isa | 1 + src/arch/arm/nativetrace.cc | 3 ++- 8 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 78ad39ee2a..b5f955c4b6 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -104,6 +104,7 @@ enum IntRegIndex INTREG_UREG0, INTREG_RHI, INTREG_RLO, + INTREG_CONDCODES, NUM_INTREGS, NUM_ARCH_INTREGS = INTREG_PC + 1, diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index a999b52e97..ebadeb9852 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -91,9 +91,9 @@ format DataOp { 0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub); 0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb); 0x4: add({{ Rd = resTemp = Rn + op2; }}, add); - 0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add); - 0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub); - 0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb); + 0x5: adc({{ Rd = resTemp = Rn + op2 + CondCodes<29:>; }}, add); + 0x6: sbc({{ Rd = resTemp = Rn - op2 - !CondCodes<29:>; }}, sub); + 0x7: rsc({{ Rd = resTemp = op2 - Rn - !CondCodes<29:>; }}, rsb); 0x8: tst({{ resTemp = Rn & op2; }}); 0x9: teq({{ resTemp = Rn ^ op2; }}); 0xa: cmp({{ resTemp = Rn - op2; }}, sub); @@ -163,9 +163,15 @@ format DataOp { 0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub); 0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb); 0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add); - 0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add); - 0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub); - 0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb); + 0x5: adci({{ + Rd = resTemp = Rn + rotated_imm + CondCodes<29:>; + }}, add); + 0x6: sbci({{ + Rd = resTemp = Rn -rotated_imm - !CondCodes<29:>; + }}, sub); + 0x7: rsci({{ + Rd = resTemp = rotated_imm - Rn - !CondCodes<29:>; + }}, rsb); 0x8: tsti({{ resTemp = Rn & rotated_imm; }}); 0x9: teqi({{ resTemp = Rn ^ rotated_imm; }}); 0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub); @@ -437,7 +443,7 @@ format DataOp { } format PredOp { // ARM System Call (SoftWare Interrupt) - 1: swi({{ if (testPredicate(Cpsr, condCode)) + 1: swi({{ if (testPredicate(CondCodes, condCode)) { if (IMMED_23_0) xc->syscall(IMMED_23_0); diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa index 95f4f14e19..5f1b541ffd 100644 --- a/src/arch/arm/isa/formats/branch.isa +++ b/src/arch/arm/isa/formats/branch.isa @@ -52,7 +52,7 @@ def format Branch(code,*opt_flags) {{ else: inst_flags += ('IsCondControl', ) - icode = 'if (testPredicate(Cpsr, condCode)) {\n' + icode = 'if (testPredicate(CondCodes, condCode)) {\n' icode += code icode += ' NPC = NPC + 4 + disp;\n' icode += '} else {\n' @@ -90,7 +90,7 @@ def format BranchExchange(code,*opt_flags) {{ #Condition code - icode = 'if (testPredicate(Cpsr, condCode)) {\n' + icode = 'if (testPredicate(CondCodes, condCode)) {\n' icode += code icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n' icode += '} else {\n' diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa index e885315808..e795296154 100644 --- a/src/arch/arm/isa/formats/fp.isa +++ b/src/arch/arm/isa/formats/fp.isa @@ -119,8 +119,8 @@ let {{ _ic = %(fReg1)s >= %(fReg2)s; _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1; - Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | - (Cpsr & 0x0FFFFFFF); + CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | + (CondCodes & 0x0FFFFFFF); ''' }}; diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa index e90788c918..3c97560fde 100644 --- a/src/arch/arm/isa/formats/pred.isa +++ b/src/arch/arm/isa/formats/pred.isa @@ -34,7 +34,7 @@ // let {{ - predicateTest = 'testPredicate(Cpsr, condCode)' + predicateTest = 'testPredicate(CondCodes, condCode)' }}; def template PredOpExecute {{ @@ -90,8 +90,8 @@ let {{ _iv = %(ivValue)s & 1; _ic = %(icValue)s & 1; - Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | - (Cpsr & 0x0FFFFFFF); + CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | + (CondCodes & 0x0FFFFFFF); DPRINTF(Arm, "in = %%d\\n", _in); DPRINTF(Arm, "iz = %%d\\n", _iz); @@ -105,8 +105,8 @@ let {{ def getCcCode(flagtype): icReg = icImm = iv = '' if flagtype == "none": - icReg = icImm = 'Cpsr<29:>' - iv = 'Cpsr<28:>' + icReg = icImm = 'CondCodes<29:>' + iv = 'CondCodes<28:>' elif flagtype == "add": icReg = icImm = 'findCarry(32, resTemp, Rn, op2)' iv = 'findOverflow(32, resTemp, Rn, op2)' @@ -117,17 +117,17 @@ let {{ icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)' iv = 'findOverflow(32, resTemp, op2, ~Rn)' else: - icReg = 'shift_carry_rs(Rm, Rs, shift, Cpsr<29:>)' - icImm = 'shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>)' - iv = 'Cpsr<28:>' + icReg = 'shift_carry_rs(Rm, Rs, shift, CondCodes<29:>)' + icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)' + iv = 'CondCodes<28:>' return (calcCcCode % {"icValue" : icReg, "ivValue" : iv}, calcCcCode % {"icValue" : icImm, "ivValue" : iv}) def getImmCcCode(flagtype): ivValue = icValue = '' if flagtype == "none": - icValue = 'Cpsr<29:>' - ivValue = 'Cpsr<28:>' + icValue = 'CondCodes<29:>' + ivValue = 'CondCodes<28:>' elif flagtype == "add": icValue = 'findCarry(32, resTemp, Rn, rotated_imm)' ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)' @@ -138,18 +138,18 @@ let {{ icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)' ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)' else: - icValue = '(rotate ? rotated_carry:Cpsr<29:>)' - ivValue = 'Cpsr<28:>' + icValue = '(rotate ? rotated_carry:CondCodes<29:>)' + ivValue = 'CondCodes<28:>' return calcCcCode % vars() }}; def format DataOp(code, flagtype = logic) {{ (regCcCode, immCcCode) = getCcCode(flagtype) regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs, - shift, Cpsr<29:0>); + shift, CondCodes<29:0>); op2 = op2;''' + code immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size, - shift, Cpsr<29:0>); + shift, CondCodes<29:0>); op2 = op2;''' + code regIop = InstObjParams(name, Name, 'PredIntOp', {"code": regCode, diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa index b5efec5682..d42ffb147e 100644 --- a/src/arch/arm/isa/formats/util.isa +++ b/src/arch/arm/isa/formats/util.isa @@ -33,8 +33,10 @@ let {{ # Generic substitutions for Arm instructions def ArmGenericCodeSubs(code): # Substitute in the shifted portion of operations - new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code) - new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code) + new_code = re.sub(r'Rm_Imm', + 'shift_rm_imm(Rm, shift_size, shift, CondCodes<29:>)', code) + new_code = re.sub(r'Rm_Rs', + 'shift_rm_rs(Rm, Rs, shift, CondCodes<29:>)', new_code) return new_code def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 4ac6790e54..02acc8ed70 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -66,6 +66,7 @@ def operands {{ 'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7), 'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8), 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9), + 'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', 'IsInteger', 10), #Register fields for microops 'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite), diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 1ad9e1a19a..01f3205eb6 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -97,7 +97,8 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc) changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]); //CPSR - newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR); + newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) | + tc->readIntReg(INTREG_CONDCODES); changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]); } From 708faa767763e65a2fded8aa33ac3c63cca9c84c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 8 Nov 2009 13:31:59 -0800 Subject: [PATCH 089/160] compile: wrap 64bit numbers with ULL() so 32bit compiles work In the isa_parser, we need to check case statements. --- src/arch/isa_parser.py | 7 ++++++- src/arch/x86/process.cc | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index e3da240d25..2db7c6aa6d 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -585,7 +585,12 @@ StaticInstPtr # 'default' def p_case_label_0(self, t): 'case_label : intlit_list' - t[0] = ': '.join(map(lambda a: 'case %#x' % a, t[1])) + def make_case(intlit): + if intlit >= 2**32: + return 'case ULL(%#x)' % intlit + else: + return 'case %#x' % intlit + t[0] = ': '.join(map(make_case, t[1])) def p_case_label_1(self, t): 'case_label : DEFAULT' diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 7cc889d7cc..42ca7b27d7 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -175,7 +175,7 @@ I386LiveProcess::I386LiveProcess(LiveProcessParams *params, int _numSyscallDescs) : X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs) { - _gdtStart = 0x100000000; + _gdtStart = ULL(0x100000000); _gdtSize = VMPageSize; vsyscallPage.base = 0xffffe000ULL; From bb903b6514b743e93e429929776639879d6c59a7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 15:16:59 -0800 Subject: [PATCH 090/160] ARM: Simplify the load/store multiple generation code. Specifically, get rid of the big switch statement so more cases can be handled. Enumerating all the possible settings doesn't scale well. Also do some minor style clean up. --- src/arch/arm/isa/formats/macromem.isa | 83 +++++++++------------------ 1 file changed, 27 insertions(+), 56 deletions(-) diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index d978967ac2..8c8ba8a1a2 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -178,75 +178,46 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; - uint32_t regs_to_handle = reglist; - uint32_t start_addr = 0; + uint32_t regs = reglist; + uint32_t addr = 0; - switch (puswl) - { - case 0x00: // stmda - case 0x01: // L ldmda_l - case 0x02: // W stmda_w - case 0x03: // WL ldmda_wl - start_addr = (ones << 2) - 4; - break; - case 0x08: // U stmia_u - case 0x09: // U L ldmia_ul - case 0x0a: // U W stmia - case 0x0b: // U WL ldmia - start_addr = 0; - break; - case 0x10: // P stmdb - case 0x11: // P L ldmdb - case 0x12: // P W stmdb - case 0x13: // P WL ldmdb - start_addr = (ones << 2); // U-bit is already 0 for subtract - break; - case 0x18: // PU stmib - case 0x19: // PU L ldmib - case 0x1a: // PU W stmib - case 0x1b: // PU WL ldmib - start_addr = 4; - break; - default: - panic("Unhandled Load/Store Multiple Instruction, " - "puswl = 0x%x", (unsigned) puswl); - break; - } + if (!up) + addr = (ones << 2) - 4; + + if (prepost) + addr += 4; // Add 0 to Rn and stick it in ureg0. // This is equivalent to a move. microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0); - unsigned j = 0; - for (int i = 1; i < ones+1; i++) { - // Get next available bit for transfer - while (! ( regs_to_handle & (1<setLastMicroop(); + lastUop->setLastMicroop(); } }}; @@ -287,14 +258,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) if (writeback) { if (up) { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroAddiUop(machInst, RN, RN, disp8); } else { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroSubiUop(machInst, RN, RN, disp8); } } - microOps[numMicroops-1]->setLastMicroop(); + microOps[numMicroops - 1]->setLastMicroop(); } }}; @@ -318,14 +289,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) if (writeback) { if (up) { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroAddiUop(machInst, RN, RN, disp8); } else { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroSubiUop(machInst, RN, RN, disp8); } } - microOps[numMicroops-1]->setLastMicroop(); + microOps[numMicroops - 1]->setLastMicroop(); } }}; From 8a4af3668dd8c45de4b98f3eb1fb2ef28bd369a2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 15:49:03 -0800 Subject: [PATCH 091/160] ARM: Support forcing load/store multiple to use user registers. --- src/arch/arm/insts/macromem.hh | 25 ++++++------------------- src/arch/arm/intregs.hh | 7 +++++++ src/arch/arm/isa.hh | 5 ++++- src/arch/arm/isa/formats/macromem.isa | 21 +++++++++++++++------ 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh index 541c9e3f55..714b8bb7ed 100644 --- a/src/arch/arm/insts/macromem.hh +++ b/src/arch/arm/insts/macromem.hh @@ -84,33 +84,20 @@ class MicroMemOp : public MicroIntOp */ class ArmMacroMemoryOp : public PredMacroOp { - protected: + protected: /// Memory request flags. See mem_req_base.hh. unsigned memAccessFlags; uint32_t reglist; uint32_t ones; - uint32_t puswl, - prepost, - up, - psruser, - writeback, - loadop; ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) - : PredMacroOp(mnem, _machInst, __opClass), - memAccessFlags(0), - reglist(machInst.regList), ones(0), - puswl(machInst.puswl), - prepost(machInst.puswl.prepost), - up(machInst.puswl.up), - psruser(machInst.puswl.psruser), - writeback(machInst.puswl.writeback), - loadop(machInst.puswl.loadOp) + : PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0), + reglist(machInst.regList), ones(0) { ones = number_of_ones(reglist); - numMicroops = ones + writeback + 1; + numMicroops = ones + machInst.puswl.writeback + 1; // Remember that writeback adds a uop microOps = new StaticInstPtr[numMicroops]; } @@ -121,7 +108,7 @@ class ArmMacroMemoryOp : public PredMacroOp */ class ArmMacroFPAOp : public PredMacroOp { - protected: + protected: uint32_t puswl, prepost, up, @@ -150,7 +137,7 @@ class ArmMacroFPAOp : public PredMacroOp */ class ArmMacroFMOp : public PredMacroOp { - protected: + protected: uint32_t punwl, prepost, up, diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index b5f955c4b6..0c2fc5fbbb 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -324,6 +324,13 @@ INTREG_FIQ(unsigned index) return IntRegFiqMap[index]; } +static inline IntRegIndex +intRegForceUser(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return (IntRegIndex)(index + NUM_INTREGS); +} + } #endif diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index f8359679b2..a4a328614e 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -125,8 +125,11 @@ namespace ArmISA assert(reg >= 0); if (reg < NUM_ARCH_INTREGS) { return intRegMap[reg]; + } else if (reg < NUM_INTREGS) { + return reg; } else { - assert(reg < NUM_INTREGS); + reg -= NUM_INTREGS; + assert(reg < NUM_ARCH_INTREGS); return reg; } } diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 8c8ba8a1a2..9a3185af33 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -180,11 +180,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) %(constructor)s; uint32_t regs = reglist; uint32_t addr = 0; + bool up = machInst.puswl.up; if (!up) addr = (ones << 2) - 4; - if (prepost) + if (machInst.puswl.prepost) addr += 4; // Add 0 to Rn and stick it in ureg0. @@ -198,10 +199,18 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) reg++; replaceBits(regs, reg, 0); - if (loadop) - microOps[i] = new MicroLdrUop(machInst, reg, INTREG_UREG0, addr); - else - microOps[i] = new MicroStrUop(machInst, reg, INTREG_UREG0, addr); + unsigned regIdx = reg; + if (machInst.puswl.psruser) { + regIdx = intRegForceUser(regIdx); + } + + if (machInst.puswl.loadOp) { + microOps[i] = + new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr); + } else { + microOps[i] = + new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr); + } if (up) addr += 4; @@ -210,7 +219,7 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) } StaticInstPtr &lastUop = microOps[numMicroops - 1]; - if (writeback) { + if (machInst.puswl.writeback) { if (up) { lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4); } else { From 374d337693a53c7c7096b55537b20980a29a3e74 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sun, 8 Nov 2009 17:35:49 -0800 Subject: [PATCH 092/160] scons: deal with generated .py files properly --- src/SConscript | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/SConscript b/src/SConscript index 35753ce4ca..d02d2a6e7c 100644 --- a/src/SConscript +++ b/src/SConscript @@ -132,15 +132,15 @@ class PySource(SourceFile): modpath = '.'.join(modpath) arcpath = path + [ self.basename ] - debugname = self.snode.abspath - if not exists(debugname): - debugname = self.tnode.abspath + abspath = self.snode.abspath + if not exists(abspath): + abspath = self.tnode.abspath self.package = package self.modname = modname self.modpath = modpath self.arcname = joinpath(*arcpath) - self.debugname = debugname + self.abspath = abspath self.compiled = File(self.filename + 'c') self.assembly = File(self.filename + '.s') self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath) @@ -339,9 +339,9 @@ class DictImporter(object): source = self.modules[fullname] if source.modname == '__init__': mod.__path__ = source.modpath - mod.__file__ = source.snode.abspath + mod.__file__ = source.abspath - exec file(source.snode.abspath, 'r') in mod.__dict__ + exec file(source.abspath, 'r') in mod.__dict__ return mod @@ -892,7 +892,7 @@ def objectifyPyFile(target, source, env): dst = file(str(target[0]), 'w') pysource = PySource.tnodes[source[0]] - compiled = compile(src, pysource.debugname, 'exec') + compiled = compile(src, pysource.abspath, 'exec') marshalled = marshal.dumps(compiled) compressed = zlib.compress(marshalled) data = compressed From 14b51697500b71a05c67c8197c017cb6a39b57a7 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 8 Nov 2009 20:15:23 -0800 Subject: [PATCH 093/160] tests: update statistics for change caused by vsyscall support in x86 Caused by a slight change in memory layout. --- .../ref/x86/linux/simple-timing/config.ini | 3 - .../ref/x86/linux/simple-timing/simout | 10 +- .../ref/x86/linux/simple-timing/stats.txt | 180 +++++++------- .../ref/x86/linux/simple-timing/config.ini | 5 +- .../10.mcf/ref/x86/linux/simple-timing/simout | 12 +- .../ref/x86/linux/simple-timing/stats.txt | 194 +++++++-------- .../ref/x86/linux/simple-timing/config.ini | 3 - .../ref/x86/linux/simple-timing/simout | 10 +- .../ref/x86/linux/simple-timing/stats.txt | 220 +++++++++--------- .../ref/x86/linux/simple-timing/config.ini | 3 - .../ref/x86/linux/simple-timing/simout | 10 +- .../ref/x86/linux/simple-timing/stats.txt | 186 +++++++-------- .../ref/x86/linux/simple-timing/config.ini | 5 +- .../ref/x86/linux/simple-timing/simout | 12 +- .../ref/x86/linux/simple-timing/stats.txt | 172 +++++++------- 15 files changed, 505 insertions(+), 520 deletions(-) diff --git a/tests/long/00.gzip/ref/x86/linux/simple-timing/config.ini b/tests/long/00.gzip/ref/x86/linux/simple-timing/config.ini index 033ea4c681..0c81e91291 100644 --- a/tests/long/00.gzip/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/00.gzip/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 diff --git a/tests/long/00.gzip/ref/x86/linux/simple-timing/simout b/tests/long/00.gzip/ref/x86/linux/simple-timing/simout index 7e3ef4fb79..8936a60947 100755 --- a/tests/long/00.gzip/ref/x86/linux/simple-timing/simout +++ b/tests/long/00.gzip/ref/x86/linux/simple-timing/simout @@ -5,10 +5,10 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 8 2009 12:09:45 -M5 revision f8cd1918b0c6 6483 default qtip tip condmovezerostats.patch -M5 started Aug 8 2009 12:09:46 -M5 executing on tater +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:32:22 +M5 executing on maize command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/00.gzip/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/00.gzip/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -44,4 +44,4 @@ Uncompressing Data Uncompressed data 1048576 bytes in length Uncompressed data compared correctly Tested 1MB buffer: OK! -Exiting @ tick 1814896735000 because target called exit() +Exiting @ tick 1814726932000 because target called exit() diff --git a/tests/long/00.gzip/ref/x86/linux/simple-timing/stats.txt b/tests/long/00.gzip/ref/x86/linux/simple-timing/stats.txt index 574e2f3812..60806dc720 100644 --- a/tests/long/00.gzip/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/00.gzip/ref/x86/linux/simple-timing/stats.txt @@ -1,76 +1,76 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 989143 # Simulator instruction rate (inst/s) -host_mem_usage 205900 # Number of bytes of host memory used -host_seconds 1637.14 # Real time elapsed on the host -host_tick_rate 1108576660 # Simulator tick rate (ticks/s) +host_inst_rate 1181561 # Simulator instruction rate (inst/s) +host_mem_usage 194380 # Number of bytes of host memory used +host_seconds 1370.53 # Real time elapsed on the host +host_tick_rate 1324103876 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 1619366736 # Number of instructions simulated -sim_seconds 1.814897 # Number of seconds simulated -sim_ticks 1814896735000 # Number of ticks simulated +sim_seconds 1.814727 # Number of seconds simulated +sim_ticks 1814726932000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 419042118 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 20939.027041 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 17939.027041 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 418844309 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 4141928000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.000472 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 197809 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 3548501000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.000472 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 197809 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_avg_miss_latency 20884.820230 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 17884.820230 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 418844783 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 4121306000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.000471 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 197335 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 3529301000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.000471 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 197335 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 188186056 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 56000 # average WriteReq miss latency system.cpu.dcache.WriteReq_avg_mshr_miss_latency 53000 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 187873910 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 17480176000 # number of WriteReq miss cycles -system.cpu.dcache.WriteReq_miss_rate 0.001659 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 312146 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 16543738000 # number of WriteReq MSHR miss cycles -system.cpu.dcache.WriteReq_mshr_miss_rate 0.001659 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 312146 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_hits 187876631 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 17327800000 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.001644 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 309425 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 16399525000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.001644 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 309425 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 1364.014744 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 1372.614288 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 607228174 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 42400.023531 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 39400.023531 # average overall mshr miss latency -system.cpu.dcache.demand_hits 606718219 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 21622104000 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.000840 # miss rate for demand accesses -system.cpu.dcache.demand_misses 509955 # number of demand (read+write) misses +system.cpu.dcache.demand_avg_miss_latency 42325.964954 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 39325.964954 # average overall mshr miss latency +system.cpu.dcache.demand_hits 606721414 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 21449106000 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.000835 # miss rate for demand accesses +system.cpu.dcache.demand_misses 506760 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 20092239000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.000840 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 509955 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 19928826000 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.000835 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 506760 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 607228174 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 42400.023531 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 39400.023531 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 42325.964954 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 39325.964954 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 606718219 # number of overall hits -system.cpu.dcache.overall_miss_latency 21622104000 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.000840 # miss rate for overall accesses -system.cpu.dcache.overall_misses 509955 # number of overall misses +system.cpu.dcache.overall_hits 606721414 # number of overall hits +system.cpu.dcache.overall_miss_latency 21449106000 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.000835 # miss rate for overall accesses +system.cpu.dcache.overall_misses 506760 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 20092239000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.000840 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 509955 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 19928826000 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.000835 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 506760 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 440755 # number of replacements -system.cpu.dcache.sampled_refs 444851 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 437970 # number of replacements +system.cpu.dcache.sampled_refs 442066 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 4094.900211 # Cycle average of tags in use -system.cpu.dcache.total_refs 606783323 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 4094.901154 # Cycle average of tags in use +system.cpu.dcache.total_refs 606786108 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 779430000 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 308934 # number of writebacks +system.cpu.dcache.writebacks 306212 # number of writebacks system.cpu.icache.ReadReq_accesses 1186516703 # number of ReadReq accesses(hits+misses) system.cpu.icache.ReadReq_avg_miss_latency 56000 # average ReadReq miss latency system.cpu.icache.ReadReq_avg_mshr_miss_latency 53000 # average ReadReq mshr miss latency @@ -120,86 +120,86 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 4 # number of replacements system.cpu.icache.sampled_refs 722 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 660.162690 # Cycle average of tags in use +system.cpu.icache.tagsinuse 660.164909 # Cycle average of tags in use system.cpu.icache.total_refs 1186515981 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 247042 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_accesses 244731 # number of ReadExReq accesses(hits+misses) system.cpu.l2cache.ReadExReq_avg_miss_latency 52000 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 12846184000 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 12726012000 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 247042 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 9881680000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 244731 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 9789240000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 247042 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 198531 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_mshr_misses 244731 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 198057 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 165128 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 1736956000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.168251 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 33403 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 1336120000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.168251 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 33403 # number of ReadReq MSHR misses -system.cpu.l2cache.UpgradeReq_accesses 65104 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_hits 164987 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 1719640000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.166972 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 33070 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 1322800000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.166972 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 33070 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 64694 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 52000 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency -system.cpu.l2cache.UpgradeReq_miss_latency 3385408000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_latency 3364088000 # number of UpgradeReq miss cycles system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_misses 65104 # number of UpgradeReq misses -system.cpu.l2cache.UpgradeReq_mshr_miss_latency 2604160000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_misses 64694 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 2587760000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_mshr_misses 65104 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 308934 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 308934 # number of Writeback hits +system.cpu.l2cache.UpgradeReq_mshr_misses 64694 # number of UpgradeReq MSHR misses +system.cpu.l2cache.Writeback_accesses 306212 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 306212 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 3.437895 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 3.429569 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 445573 # number of demand (read+write) accesses +system.cpu.l2cache.demand_accesses 442788 # number of demand (read+write) accesses system.cpu.l2cache.demand_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 165128 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 14583140000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.629403 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 280445 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 164987 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 14445652000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.627391 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 277801 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 11217800000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.629403 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 280445 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 11112040000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.627391 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 277801 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 445573 # number of overall (read+write) accesses +system.cpu.l2cache.overall_accesses 442788 # number of overall (read+write) accesses system.cpu.l2cache.overall_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 165128 # number of overall hits -system.cpu.l2cache.overall_miss_latency 14583140000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.629403 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 280445 # number of overall misses +system.cpu.l2cache.overall_hits 164987 # number of overall hits +system.cpu.l2cache.overall_miss_latency 14445652000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.627391 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 277801 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 11217800000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.629403 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 280445 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 11112040000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.627391 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 277801 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.l2cache.replacements 82239 # number of replacements -system.cpu.l2cache.sampled_refs 97729 # Sample count of references to valid blocks. +system.cpu.l2cache.replacements 81543 # number of replacements +system.cpu.l2cache.sampled_refs 97060 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 16489.401861 # Cycle average of tags in use -system.cpu.l2cache.total_refs 335982 # Total number of references to valid blocks. +system.cpu.l2cache.tagsinuse 16545.401704 # Cycle average of tags in use +system.cpu.l2cache.total_refs 332874 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. -system.cpu.l2cache.writebacks 61724 # number of writebacks +system.cpu.l2cache.writebacks 61555 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 3629793470 # number of cpu cycles simulated +system.cpu.numCycles 3629453864 # number of cpu cycles simulated system.cpu.num_insts 1619366736 # Number of instructions executed system.cpu.num_refs 607228174 # Number of memory references system.cpu.workload.PROG:num_syscalls 48 # Number of system calls diff --git a/tests/long/10.mcf/ref/x86/linux/simple-timing/config.ini b/tests/long/10.mcf/ref/x86/linux/simple-timing/config.ini index 40547fe1c7..c90ba3ccfd 100644 --- a/tests/long/10.mcf/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/10.mcf/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 @@ -152,7 +149,7 @@ type=ExeTracer [system.cpu.workload] type=LiveProcess cmd=mcf mcf.in -cwd=build/X86_SE/tests/opt/long/10.mcf/x86/linux/simple-timing +cwd=build/X86_SE/tests/fast/long/10.mcf/x86/linux/simple-timing egid=100 env= errout=cerr diff --git a/tests/long/10.mcf/ref/x86/linux/simple-timing/simout b/tests/long/10.mcf/ref/x86/linux/simple-timing/simout index 2a93c45ae2..035c663f28 100755 --- a/tests/long/10.mcf/ref/x86/linux/simple-timing/simout +++ b/tests/long/10.mcf/ref/x86/linux/simple-timing/simout @@ -5,11 +5,11 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 17 2009 20:29:57 -M5 revision 84f7bdc43a4f 6605 default qtip tip x86fsdate.patch -M5 started Aug 17 2009 20:30:53 -M5 executing on tater -command line: build/X86_SE/m5.opt -d build/X86_SE/tests/opt/long/10.mcf/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/opt/long/10.mcf/x86/linux/simple-timing +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:34:05 +M5 executing on maize +command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/10.mcf/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/10.mcf/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -28,4 +28,4 @@ simplex iterations : 2663 flow value : 3080014995 checksum : 68389 optimal -Exiting @ tick 381620562000 because target called exit() +Exiting @ tick 382091472000 because target called exit() diff --git a/tests/long/10.mcf/ref/x86/linux/simple-timing/stats.txt b/tests/long/10.mcf/ref/x86/linux/simple-timing/stats.txt index a882827d54..b582ff4051 100644 --- a/tests/long/10.mcf/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/10.mcf/ref/x86/linux/simple-timing/stats.txt @@ -1,76 +1,76 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 395133 # Simulator instruction rate (inst/s) -host_mem_usage 355296 # Number of bytes of host memory used -host_seconds 682.55 # Real time elapsed on the host -host_tick_rate 559113861 # Simulator tick rate (ticks/s) +host_inst_rate 839358 # Simulator instruction rate (inst/s) +host_mem_usage 328912 # Number of bytes of host memory used +host_seconds 321.31 # Real time elapsed on the host +host_tick_rate 1189158712 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 269695959 # Number of instructions simulated -sim_seconds 0.381621 # Number of seconds simulated -sim_ticks 381620562000 # Number of ticks simulated +sim_seconds 0.382091 # Number of seconds simulated +sim_ticks 382091472000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 90779443 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 15899.099984 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 12899.099984 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 88829255 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 31006234000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.021483 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 1950188 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 25155670000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.021483 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 1950188 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_avg_miss_latency 15892.729148 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 12892.729148 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 88818985 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 31157028000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.021596 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 1960458 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 25275654000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.021596 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 1960458 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 31439750 # number of WriteReq accesses(hits+misses) -system.cpu.dcache.WriteReq_avg_miss_latency 56000.034908 # average WriteReq miss latency -system.cpu.dcache.WriteReq_avg_mshr_miss_latency 53000.034908 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 31210573 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 12833920000 # number of WriteReq miss cycles -system.cpu.dcache.WriteReq_miss_rate 0.007289 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 229177 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 12146389000 # number of WriteReq MSHR miss cycles -system.cpu.dcache.WriteReq_mshr_miss_rate 0.007289 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 229177 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_avg_miss_latency 56000.038268 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 53000.038268 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 31204566 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 13170313000 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.007480 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 235184 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 12464761000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.007480 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 235184 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 58.501856 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 58.134189 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 122219193 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 20116.021869 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 17116.021869 # average overall mshr miss latency -system.cpu.dcache.demand_hits 120039828 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 43840154000 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.017832 # miss rate for demand accesses -system.cpu.dcache.demand_misses 2179365 # number of demand (read+write) misses +system.cpu.dcache.demand_avg_miss_latency 20188.783508 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 17188.783508 # average overall mshr miss latency +system.cpu.dcache.demand_hits 120023551 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 44327341000 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.017965 # miss rate for demand accesses +system.cpu.dcache.demand_misses 2195642 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 37302059000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.017832 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 2179365 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 37740415000 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.017965 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 2195642 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 122219193 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 20116.021869 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 17116.021869 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 20188.783508 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 17188.783508 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 120039828 # number of overall hits -system.cpu.dcache.overall_miss_latency 43840154000 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.017832 # miss rate for overall accesses -system.cpu.dcache.overall_misses 2179365 # number of overall misses +system.cpu.dcache.overall_hits 120023551 # number of overall hits +system.cpu.dcache.overall_miss_latency 44327341000 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.017965 # miss rate for overall accesses +system.cpu.dcache.overall_misses 2195642 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 37302059000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.017832 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 2179365 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 37740415000 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.017965 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 2195642 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 2049944 # number of replacements -system.cpu.dcache.sampled_refs 2054040 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 2062715 # number of replacements +system.cpu.dcache.sampled_refs 2066811 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 4079.426853 # Cycle average of tags in use -system.cpu.dcache.total_refs 120165153 # Total number of references to valid blocks. -system.cpu.dcache.warmup_cycle 127225673000 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 229129 # number of writebacks +system.cpu.dcache.tagsinuse 4077.137530 # Cycle average of tags in use +system.cpu.dcache.total_refs 120152382 # Total number of references to valid blocks. +system.cpu.dcache.warmup_cycle 127457925000 # Cycle when the warmup percentage was hit. +system.cpu.dcache.writebacks 235136 # number of writebacks system.cpu.icache.ReadReq_accesses 217696172 # number of ReadReq accesses(hits+misses) system.cpu.icache.ReadReq_avg_miss_latency 56000 # average ReadReq miss latency system.cpu.icache.ReadReq_avg_mshr_miss_latency 53000 # average ReadReq mshr miss latency @@ -120,86 +120,86 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 24 # number of replacements system.cpu.icache.sampled_refs 808 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 667.511289 # Cycle average of tags in use +system.cpu.icache.tagsinuse 667.480800 # Cycle average of tags in use system.cpu.icache.total_refs 217695364 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 103852 # number of ReadExReq accesses(hits+misses) -system.cpu.l2cache.ReadExReq_avg_miss_latency 52000.298502 # average ReadExReq miss latency +system.cpu.l2cache.ReadExReq_accesses 106353 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_avg_miss_latency 52000.291482 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 5400335000 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 5530387000 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 103852 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 4154080000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 106353 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 4254120000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 103852 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 1950996 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_mshr_misses 106353 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 1961266 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 1862007 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 4627428000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.045612 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 88989 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 3559560000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.045612 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 88989 # number of ReadReq MSHR misses -system.cpu.l2cache.UpgradeReq_accesses 125325 # number of UpgradeReq accesses(hits+misses) -system.cpu.l2cache.UpgradeReq_avg_miss_latency 51990.456812 # average UpgradeReq miss latency +system.cpu.l2cache.ReadReq_hits 1872110 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 4636112000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.045458 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 89156 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 3566240000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.045458 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 89156 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 128831 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.UpgradeReq_avg_miss_latency 51991.120150 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency -system.cpu.l2cache.UpgradeReq_miss_latency 6515704000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_latency 6698068000 # number of UpgradeReq miss cycles system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_misses 125325 # number of UpgradeReq misses -system.cpu.l2cache.UpgradeReq_mshr_miss_latency 5013000000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_misses 128831 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 5153240000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_mshr_misses 125325 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 229129 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 229129 # number of Writeback hits +system.cpu.l2cache.UpgradeReq_mshr_misses 128831 # number of UpgradeReq MSHR misses +system.cpu.l2cache.Writeback_accesses 235136 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 235136 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 13.678118 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 13.775269 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 2054848 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 52000.160754 # average overall miss latency +system.cpu.l2cache.demand_accesses 2067619 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 52000.158560 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 1862007 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 10027763000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.093847 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 192841 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 1872110 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 10166499000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.094558 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 195509 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 7713640000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.093847 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 192841 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 7820360000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.094558 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 195509 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 2054848 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 52000.160754 # average overall miss latency +system.cpu.l2cache.overall_accesses 2067619 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 52000.158560 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 1862007 # number of overall hits -system.cpu.l2cache.overall_miss_latency 10027763000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.093847 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 192841 # number of overall misses +system.cpu.l2cache.overall_hits 1872110 # number of overall hits +system.cpu.l2cache.overall_miss_latency 10166499000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.094558 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 195509 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 7713640000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.093847 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 192841 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 7820360000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.094558 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 195509 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.l2cache.replacements 108886 # number of replacements -system.cpu.l2cache.sampled_refs 132828 # Sample count of references to valid blocks. +system.cpu.l2cache.replacements 109056 # number of replacements +system.cpu.l2cache.sampled_refs 132990 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 18003.313178 # Cycle average of tags in use -system.cpu.l2cache.total_refs 1816837 # Total number of references to valid blocks. +system.cpu.l2cache.tagsinuse 18001.651383 # Cycle average of tags in use +system.cpu.l2cache.total_refs 1831973 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. -system.cpu.l2cache.writebacks 70892 # number of writebacks +system.cpu.l2cache.writebacks 70891 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 763241124 # number of cpu cycles simulated +system.cpu.numCycles 764182944 # number of cpu cycles simulated system.cpu.num_insts 269695959 # Number of instructions executed system.cpu.num_refs 122219131 # Number of memory references system.cpu.workload.PROG:num_syscalls 444 # Number of system calls diff --git a/tests/long/20.parser/ref/x86/linux/simple-timing/config.ini b/tests/long/20.parser/ref/x86/linux/simple-timing/config.ini index 5f5b1b01c2..a7ed66f8ac 100644 --- a/tests/long/20.parser/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/20.parser/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 diff --git a/tests/long/20.parser/ref/x86/linux/simple-timing/simout b/tests/long/20.parser/ref/x86/linux/simple-timing/simout index a5dbe2b410..a11db4e1ea 100755 --- a/tests/long/20.parser/ref/x86/linux/simple-timing/simout +++ b/tests/long/20.parser/ref/x86/linux/simple-timing/simout @@ -5,10 +5,10 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 8 2009 12:09:45 -M5 revision f8cd1918b0c6 6483 default qtip tip condmovezerostats.patch -M5 started Aug 8 2009 12:09:46 -M5 executing on tater +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:39:28 +M5 executing on maize command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/20.parser/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/20.parser/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -74,4 +74,4 @@ info: Increasing stack size by one page. about 2 million people attended the five best costumes got prizes No errors! -Exiting @ tick 1722352562000 because target called exit() +Exiting @ tick 1722331568000 because target called exit() diff --git a/tests/long/20.parser/ref/x86/linux/simple-timing/stats.txt b/tests/long/20.parser/ref/x86/linux/simple-timing/stats.txt index c62dd07543..0e665b6ef7 100644 --- a/tests/long/20.parser/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/20.parser/ref/x86/linux/simple-timing/stats.txt @@ -1,84 +1,84 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 924480 # Simulator instruction rate (inst/s) -host_mem_usage 209588 # Number of bytes of host memory used -host_seconds 1617.88 # Real time elapsed on the host -host_tick_rate 1064572030 # Simulator tick rate (ticks/s) +host_inst_rate 1459378 # Simulator instruction rate (inst/s) +host_mem_usage 198104 # Number of bytes of host memory used +host_seconds 1024.89 # Real time elapsed on the host +host_tick_rate 1680505604 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 1495700470 # Number of instructions simulated -sim_seconds 1.722353 # Number of seconds simulated -sim_ticks 1722352562000 # Number of ticks simulated +sim_seconds 1.722332 # Number of seconds simulated +sim_ticks 1722331568000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 384102182 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 24147.662775 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 21147.661617 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 382375369 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 41698498000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.004496 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 1726813 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 36518057000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.004496 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 1726813 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_avg_miss_latency 24153.691272 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 21153.690114 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 382374810 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 41722410000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.004497 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 1727372 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 36540292000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.004497 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 1727372 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 149160200 # number of WriteReq accesses(hits+misses) -system.cpu.dcache.WriteReq_avg_miss_latency 55999.912355 # average WriteReq miss latency -system.cpu.dcache.WriteReq_avg_mshr_miss_latency 52999.912355 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 147694052 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 82104159500 # number of WriteReq miss cycles -system.cpu.dcache.WriteReq_miss_rate 0.009829 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 1466148 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 77705715500 # number of WriteReq MSHR miss cycles -system.cpu.dcache.WriteReq_mshr_miss_rate 0.009829 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 1466148 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_avg_miss_latency 55999.912307 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 52999.912307 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 147694869 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 82058407500 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.009824 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 1465331 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 77662414500 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.009824 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 1465331 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 210.782575 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 210.745406 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 533262382 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 38773.620317 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 35773.619690 # average overall mshr miss latency -system.cpu.dcache.demand_hits 530069421 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 123802657500 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.005988 # miss rate for demand accesses -system.cpu.dcache.demand_misses 3192961 # number of demand (read+write) misses +system.cpu.dcache.demand_avg_miss_latency 38769.912986 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 35769.912360 # average overall mshr miss latency +system.cpu.dcache.demand_hits 530069679 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 123780817500 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.005987 # miss rate for demand accesses +system.cpu.dcache.demand_misses 3192703 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 114223772500 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.005988 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 3192961 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 114202706500 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.005987 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 3192703 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 533262382 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 38773.620317 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 35773.619690 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 38769.912986 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 35769.912360 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 530069421 # number of overall hits -system.cpu.dcache.overall_miss_latency 123802657500 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.005988 # miss rate for overall accesses -system.cpu.dcache.overall_misses 3192961 # number of overall misses +system.cpu.dcache.overall_hits 530069679 # number of overall hits +system.cpu.dcache.overall_miss_latency 123780817500 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.005987 # miss rate for overall accesses +system.cpu.dcache.overall_misses 3192703 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 114223772500 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.005988 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 3192961 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 114202706500 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.005987 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 3192703 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 2513875 # number of replacements -system.cpu.dcache.sampled_refs 2517971 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 2514317 # number of replacements +system.cpu.dcache.sampled_refs 2518413 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 4086.831173 # Cycle average of tags in use -system.cpu.dcache.total_refs 530744411 # Total number of references to valid blocks. -system.cpu.dcache.warmup_cycle 8217762000 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 1463913 # number of writebacks +system.cpu.dcache.tagsinuse 4086.814341 # Cycle average of tags in use +system.cpu.dcache.total_refs 530743969 # Total number of references to valid blocks. +system.cpu.dcache.warmup_cycle 8217895000 # Cycle when the warmup percentage was hit. +system.cpu.dcache.writebacks 1463113 # number of writebacks system.cpu.icache.ReadReq_accesses 1068347073 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 48417.910448 # average ReadReq miss latency -system.cpu.icache.ReadReq_avg_mshr_miss_latency 45417.910448 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_avg_miss_latency 48626.865672 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 45626.865672 # average ReadReq mshr miss latency system.cpu.icache.ReadReq_hits 1068344259 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 136248000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_latency 136836000 # number of ReadReq miss cycles system.cpu.icache.ReadReq_miss_rate 0.000003 # miss rate for ReadReq accesses system.cpu.icache.ReadReq_misses 2814 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_miss_latency 127806000 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_latency 128394000 # number of ReadReq MSHR miss cycles system.cpu.icache.ReadReq_mshr_miss_rate 0.000003 # mshr miss rate for ReadReq accesses system.cpu.icache.ReadReq_mshr_misses 2814 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked @@ -90,29 +90,29 @@ system.cpu.icache.blocked_cycles::no_mshrs 0 # system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed system.cpu.icache.demand_accesses 1068347073 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 48417.910448 # average overall miss latency -system.cpu.icache.demand_avg_mshr_miss_latency 45417.910448 # average overall mshr miss latency +system.cpu.icache.demand_avg_miss_latency 48626.865672 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 45626.865672 # average overall mshr miss latency system.cpu.icache.demand_hits 1068344259 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 136248000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_latency 136836000 # number of demand (read+write) miss cycles system.cpu.icache.demand_miss_rate 0.000003 # miss rate for demand accesses system.cpu.icache.demand_misses 2814 # number of demand (read+write) misses system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.icache.demand_mshr_miss_latency 127806000 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_latency 128394000 # number of demand (read+write) MSHR miss cycles system.cpu.icache.demand_mshr_miss_rate 0.000003 # mshr miss rate for demand accesses system.cpu.icache.demand_mshr_misses 2814 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.icache.overall_accesses 1068347073 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 48417.910448 # average overall miss latency -system.cpu.icache.overall_avg_mshr_miss_latency 45417.910448 # average overall mshr miss latency +system.cpu.icache.overall_avg_miss_latency 48626.865672 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 45626.865672 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.icache.overall_hits 1068344259 # number of overall hits -system.cpu.icache.overall_miss_latency 136248000 # number of overall miss cycles +system.cpu.icache.overall_miss_latency 136836000 # number of overall miss cycles system.cpu.icache.overall_miss_rate 0.000003 # miss rate for overall accesses system.cpu.icache.overall_misses 2814 # number of overall misses system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.icache.overall_mshr_miss_latency 127806000 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_latency 128394000 # number of overall MSHR miss cycles system.cpu.icache.overall_mshr_miss_rate 0.000003 # mshr miss rate for overall accesses system.cpu.icache.overall_mshr_misses 2814 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles @@ -120,86 +120,86 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 1253 # number of replacements system.cpu.icache.sampled_refs 2814 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 887.487990 # Cycle average of tags in use +system.cpu.icache.tagsinuse 887.538461 # Cycle average of tags in use system.cpu.icache.total_refs 1068344259 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 791158 # number of ReadExReq accesses(hits+misses) -system.cpu.l2cache.ReadExReq_avg_miss_latency 52000.014536 # average ReadExReq miss latency +system.cpu.l2cache.ReadExReq_accesses 791041 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_avg_miss_latency 52000.014538 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 41140227500 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 41134143500 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 791158 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 31646320000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 791041 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 31641640000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 791158 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 1729627 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_mshr_misses 791041 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 1730186 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 1310104 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 21815196000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.242551 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 419523 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 16780920000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.242551 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 419523 # number of ReadReq MSHR misses -system.cpu.l2cache.UpgradeReq_accesses 674990 # number of UpgradeReq accesses(hits+misses) -system.cpu.l2cache.UpgradeReq_avg_miss_latency 51989.214655 # average UpgradeReq miss latency +system.cpu.l2cache.ReadReq_hits 1310266 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 21835840000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.242702 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 419920 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 16796800000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.242702 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 419920 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 674290 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.UpgradeReq_avg_miss_latency 51989.203458 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency -system.cpu.l2cache.UpgradeReq_miss_latency 35092200000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_latency 35055800000 # number of UpgradeReq miss cycles system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_misses 674990 # number of UpgradeReq misses -system.cpu.l2cache.UpgradeReq_mshr_miss_latency 26999600000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_misses 674290 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 26971600000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_mshr_misses 674990 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 1463913 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 1463913 # number of Writeback hits +system.cpu.l2cache.UpgradeReq_mshr_misses 674290 # number of UpgradeReq MSHR misses +system.cpu.l2cache.Writeback_accesses 1463113 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 1463113 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 3.428066 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 3.423900 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 2520785 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 52000.009499 # average overall miss latency +system.cpu.l2cache.demand_accesses 2521227 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 52000.009497 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 1310104 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 62955423500 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.480279 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 1210681 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 1310266 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 62969983500 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.480306 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 1210961 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 48427240000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.480279 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 1210681 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 48438440000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.480306 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 1210961 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 2520785 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 52000.009499 # average overall miss latency +system.cpu.l2cache.overall_accesses 2521227 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 52000.009497 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 1310104 # number of overall hits -system.cpu.l2cache.overall_miss_latency 62955423500 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.480279 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 1210681 # number of overall misses +system.cpu.l2cache.overall_hits 1310266 # number of overall hits +system.cpu.l2cache.overall_miss_latency 62969983500 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.480306 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 1210961 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 48427240000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.480279 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 1210681 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 48438440000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.480306 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 1210961 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.l2cache.replacements 663513 # number of replacements -system.cpu.l2cache.sampled_refs 679921 # Sample count of references to valid blocks. +system.cpu.l2cache.replacements 664073 # number of replacements +system.cpu.l2cache.sampled_refs 680479 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 17216.037197 # Cycle average of tags in use -system.cpu.l2cache.total_refs 2330814 # Total number of references to valid blocks. -system.cpu.l2cache.warmup_cycle 921771494000 # Cycle when the warmup percentage was hit. -system.cpu.l2cache.writebacks 481430 # number of writebacks +system.cpu.l2cache.tagsinuse 17213.177564 # Cycle average of tags in use +system.cpu.l2cache.total_refs 2329892 # Total number of references to valid blocks. +system.cpu.l2cache.warmup_cycle 921652677000 # Cycle when the warmup percentage was hit. +system.cpu.l2cache.writebacks 481653 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 3444705124 # number of cpu cycles simulated +system.cpu.numCycles 3444663136 # number of cpu cycles simulated system.cpu.num_insts 1495700470 # Number of instructions executed system.cpu.num_refs 533262337 # Number of memory references system.cpu.workload.PROG:num_syscalls 551 # Number of system calls diff --git a/tests/long/60.bzip2/ref/x86/linux/simple-timing/config.ini b/tests/long/60.bzip2/ref/x86/linux/simple-timing/config.ini index 2985d5b219..d5c949c6e4 100644 --- a/tests/long/60.bzip2/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/60.bzip2/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 diff --git a/tests/long/60.bzip2/ref/x86/linux/simple-timing/simout b/tests/long/60.bzip2/ref/x86/linux/simple-timing/simout index ea6185a035..8e0139bb7a 100755 --- a/tests/long/60.bzip2/ref/x86/linux/simple-timing/simout +++ b/tests/long/60.bzip2/ref/x86/linux/simple-timing/simout @@ -5,10 +5,10 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 8 2009 12:09:45 -M5 revision f8cd1918b0c6 6483 default qtip tip condmovezerostats.patch -M5 started Aug 8 2009 12:13:11 -M5 executing on tater +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:30:56 +M5 executing on maize command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/60.bzip2/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/60.bzip2/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -29,4 +29,4 @@ Uncompressing Data Uncompressed data 1048576 bytes in length Uncompressed data compared correctly Tested 1MB buffer: OK! -Exiting @ tick 5988064038000 because target called exit() +Exiting @ tick 5988037845000 because target called exit() diff --git a/tests/long/60.bzip2/ref/x86/linux/simple-timing/stats.txt b/tests/long/60.bzip2/ref/x86/linux/simple-timing/stats.txt index 129e4b8665..ffd34c1e6b 100644 --- a/tests/long/60.bzip2/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/60.bzip2/ref/x86/linux/simple-timing/stats.txt @@ -1,76 +1,76 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 1178978 # Simulator instruction rate (inst/s) -host_mem_usage 205796 # Number of bytes of host memory used -host_seconds 3946.92 # Real time elapsed on the host -host_tick_rate 1517149915 # Simulator tick rate (ticks/s) +host_inst_rate 1485872 # Simulator instruction rate (inst/s) +host_mem_usage 194272 # Number of bytes of host memory used +host_seconds 3131.72 # Real time elapsed on the host +host_tick_rate 1912063349 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 4653327894 # Number of instructions simulated -sim_seconds 5.988064 # Number of seconds simulated -sim_ticks 5988064038000 # Number of ticks simulated +sim_seconds 5.988038 # Number of seconds simulated +sim_ticks 5988037845000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 1239184742 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 25017.713978 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 22017.713978 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 1231961294 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 180714156000 # number of ReadReq miss cycles -system.cpu.dcache.ReadReq_miss_rate 0.005829 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 7223448 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 159043812000 # number of ReadReq MSHR miss cycles -system.cpu.dcache.ReadReq_mshr_miss_rate 0.005829 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 7223448 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_avg_miss_latency 25018.463901 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 22018.463901 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 1231962487 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 180689726000 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.005828 # miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_misses 7222255 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 159022961000 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.005828 # mshr miss rate for ReadReq accesses +system.cpu.dcache.ReadReq_mshr_misses 7222255 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 438528336 # number of WriteReq accesses(hits+misses) -system.cpu.dcache.WriteReq_avg_miss_latency 55999.834453 # average WriteReq miss latency -system.cpu.dcache.WriteReq_avg_mshr_miss_latency 52999.834453 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 436281234 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 125837340000 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_avg_miss_latency 55999.840680 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 52999.840680 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 436281288 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 125834330000 # number of WriteReq miss cycles system.cpu.dcache.WriteReq_miss_rate 0.005124 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 2247102 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 119096034000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_misses 2247048 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 119093186000 # number of WriteReq MSHR miss cycles system.cpu.dcache.WriteReq_mshr_miss_rate 0.005124 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 2247102 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_mshr_misses 2247048 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 183.099497 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 183.121439 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 1677713078 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 32368.922185 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 29368.922185 # average overall mshr miss latency -system.cpu.dcache.demand_hits 1668242528 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 306551496000 # number of demand (read+write) miss cycles -system.cpu.dcache.demand_miss_rate 0.005645 # miss rate for demand accesses -system.cpu.dcache.demand_misses 9470550 # number of demand (read+write) misses +system.cpu.dcache.demand_avg_miss_latency 32370.287021 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 29370.287021 # average overall mshr miss latency +system.cpu.dcache.demand_hits 1668243775 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 306524056000 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.005644 # miss rate for demand accesses +system.cpu.dcache.demand_misses 9469303 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 278139846000 # number of demand (read+write) MSHR miss cycles -system.cpu.dcache.demand_mshr_miss_rate 0.005645 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 9470550 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_miss_latency 278116147000 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.005644 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 9469303 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 1677713078 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 32368.922185 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 29368.922185 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 32370.287021 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 29370.287021 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 1668242528 # number of overall hits -system.cpu.dcache.overall_miss_latency 306551496000 # number of overall miss cycles -system.cpu.dcache.overall_miss_rate 0.005645 # miss rate for overall accesses -system.cpu.dcache.overall_misses 9470550 # number of overall misses +system.cpu.dcache.overall_hits 1668243775 # number of overall hits +system.cpu.dcache.overall_miss_latency 306524056000 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.005644 # miss rate for overall accesses +system.cpu.dcache.overall_misses 9469303 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 278139846000 # number of overall MSHR miss cycles -system.cpu.dcache.overall_mshr_miss_rate 0.005645 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 9470550 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_miss_latency 278116147000 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.005644 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 9469303 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 9108982 # number of replacements -system.cpu.dcache.sampled_refs 9113078 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 9107896 # number of replacements +system.cpu.dcache.sampled_refs 9111992 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 4084.778553 # Cycle average of tags in use -system.cpu.dcache.total_refs 1668600000 # Total number of references to valid blocks. -system.cpu.dcache.warmup_cycle 58863931000 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 2244013 # number of writebacks +system.cpu.dcache.tagsinuse 4084.774232 # Cycle average of tags in use +system.cpu.dcache.total_refs 1668601086 # Total number of references to valid blocks. +system.cpu.dcache.warmup_cycle 58863918000 # Cycle when the warmup percentage was hit. +system.cpu.dcache.writebacks 2243955 # number of writebacks system.cpu.icache.ReadReq_accesses 4013232890 # number of ReadReq accesses(hits+misses) system.cpu.icache.ReadReq_avg_miss_latency 56000 # average ReadReq miss latency system.cpu.icache.ReadReq_avg_mshr_miss_latency 53000 # average ReadReq mshr miss latency @@ -120,86 +120,86 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 10 # number of replacements system.cpu.icache.sampled_refs 675 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 555.573306 # Cycle average of tags in use +system.cpu.icache.tagsinuse 555.573148 # Cycle average of tags in use system.cpu.icache.total_refs 4013232215 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 1889630 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_accesses 1889737 # number of ReadExReq accesses(hits+misses) system.cpu.l2cache.ReadExReq_avg_miss_latency 52000 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 98260760000 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 98266324000 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 1889630 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 75585200000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 1889737 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 75589480000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 1889630 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 7224123 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_mshr_misses 1889737 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 7222930 # number of ReadReq accesses(hits+misses) system.cpu.l2cache.ReadReq_avg_miss_latency 52000 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 5328546 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 98570004000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.262395 # miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_misses 1895577 # number of ReadReq misses -system.cpu.l2cache.ReadReq_mshr_miss_latency 75823080000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.262395 # mshr miss rate for ReadReq accesses -system.cpu.l2cache.ReadReq_mshr_misses 1895577 # number of ReadReq MSHR misses -system.cpu.l2cache.UpgradeReq_accesses 357472 # number of UpgradeReq accesses(hits+misses) -system.cpu.l2cache.UpgradeReq_avg_miss_latency 51945.886671 # average UpgradeReq miss latency +system.cpu.l2cache.ReadReq_hits 5327537 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 98560436000 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.262413 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 1895393 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 75815720000 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.262413 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 1895393 # number of ReadReq MSHR misses +system.cpu.l2cache.UpgradeReq_accesses 357311 # number of UpgradeReq accesses(hits+misses) +system.cpu.l2cache.UpgradeReq_avg_miss_latency 51947.899729 # average UpgradeReq miss latency system.cpu.l2cache.UpgradeReq_avg_mshr_miss_latency 40000 # average UpgradeReq mshr miss latency -system.cpu.l2cache.UpgradeReq_miss_latency 18569200000 # number of UpgradeReq miss cycles +system.cpu.l2cache.UpgradeReq_miss_latency 18561556000 # number of UpgradeReq miss cycles system.cpu.l2cache.UpgradeReq_miss_rate 1 # miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_misses 357472 # number of UpgradeReq misses -system.cpu.l2cache.UpgradeReq_mshr_miss_latency 14298880000 # number of UpgradeReq MSHR miss cycles +system.cpu.l2cache.UpgradeReq_misses 357311 # number of UpgradeReq misses +system.cpu.l2cache.UpgradeReq_mshr_miss_latency 14292440000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses -system.cpu.l2cache.UpgradeReq_mshr_misses 357472 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 2244013 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 2244013 # number of Writeback hits +system.cpu.l2cache.UpgradeReq_mshr_misses 357311 # number of UpgradeReq MSHR misses +system.cpu.l2cache.Writeback_accesses 2243955 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 2243955 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 2.381201 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 2.380966 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 9113753 # number of demand (read+write) accesses +system.cpu.l2cache.demand_accesses 9112667 # number of demand (read+write) accesses system.cpu.l2cache.demand_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 5328546 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 196830764000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.415329 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 3785207 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 5327537 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 196826760000 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.415370 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 3785130 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 151408280000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.415329 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 3785207 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 151405200000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.415370 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 3785130 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 9113753 # number of overall (read+write) accesses +system.cpu.l2cache.overall_accesses 9112667 # number of overall (read+write) accesses system.cpu.l2cache.overall_avg_miss_latency 52000 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 5328546 # number of overall hits -system.cpu.l2cache.overall_miss_latency 196830764000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.415329 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 3785207 # number of overall misses +system.cpu.l2cache.overall_hits 5327537 # number of overall hits +system.cpu.l2cache.overall_miss_latency 196826760000 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.415370 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 3785130 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 151408280000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.415329 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 3785207 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 151405200000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.415370 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 3785130 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.l2cache.replacements 2772128 # number of replacements -system.cpu.l2cache.sampled_refs 2798338 # Sample count of references to valid blocks. +system.cpu.l2cache.replacements 2771977 # number of replacements +system.cpu.l2cache.sampled_refs 2798150 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 25742.940388 # Cycle average of tags in use -system.cpu.l2cache.total_refs 6663406 # Total number of references to valid blocks. -system.cpu.l2cache.warmup_cycle 4737814312000 # Cycle when the warmup percentage was hit. -system.cpu.l2cache.writebacks 1199171 # number of writebacks +system.cpu.l2cache.tagsinuse 25743.015890 # Cycle average of tags in use +system.cpu.l2cache.total_refs 6662299 # Total number of references to valid blocks. +system.cpu.l2cache.warmup_cycle 4737770578000 # Cycle when the warmup percentage was hit. +system.cpu.l2cache.writebacks 1199166 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 11976128076 # number of cpu cycles simulated +system.cpu.numCycles 11976075690 # number of cpu cycles simulated system.cpu.num_insts 4653327894 # Number of instructions executed system.cpu.num_refs 1677713078 # Number of memory references system.cpu.workload.PROG:num_syscalls 46 # Number of system calls diff --git a/tests/long/70.twolf/ref/x86/linux/simple-timing/config.ini b/tests/long/70.twolf/ref/x86/linux/simple-timing/config.ini index f70defe2b6..6cbe3be3b9 100644 --- a/tests/long/70.twolf/ref/x86/linux/simple-timing/config.ini +++ b/tests/long/70.twolf/ref/x86/linux/simple-timing/config.ini @@ -45,7 +45,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -80,7 +79,6 @@ hash_delay=1 latency=1000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=10000 @@ -115,7 +113,6 @@ hash_delay=1 latency=10000 max_miss_count=0 mshrs=10 -prefetch_cache_check_push=true prefetch_data_accesses_only=false prefetch_degree=1 prefetch_latency=100000 @@ -152,7 +149,7 @@ type=ExeTracer [system.cpu.workload] type=LiveProcess cmd=twolf smred -cwd=build/X86_SE/tests/opt/long/70.twolf/x86/linux/simple-timing +cwd=build/X86_SE/tests/fast/long/70.twolf/x86/linux/simple-timing egid=100 env= errout=cerr diff --git a/tests/long/70.twolf/ref/x86/linux/simple-timing/simout b/tests/long/70.twolf/ref/x86/linux/simple-timing/simout index cfb8745b2b..32ad086006 100755 --- a/tests/long/70.twolf/ref/x86/linux/simple-timing/simout +++ b/tests/long/70.twolf/ref/x86/linux/simple-timing/simout @@ -5,11 +5,11 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Aug 17 2009 20:29:57 -M5 revision 84f7bdc43a4f 6605 default qtip tip x86fsdate.patch -M5 started Aug 17 2009 20:42:16 -M5 executing on tater -command line: build/X86_SE/m5.opt -d build/X86_SE/tests/opt/long/70.twolf/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/opt/long/70.twolf/x86/linux/simple-timing +M5 compiled Nov 8 2009 16:16:58 +M5 revision 5d58e4833e79 6726 default qtip tip x86_tests.diff +M5 started Nov 8 2009 16:37:25 +M5 executing on maize +command line: build/X86_SE/m5.fast -d build/X86_SE/tests/fast/long/70.twolf/x86/linux/simple-timing -re tests/run.py build/X86_SE/tests/fast/long/70.twolf/x86/linux/simple-timing Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... @@ -27,4 +27,4 @@ info: Increasing stack size by one page. 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 -122 123 124 Exiting @ tick 250961789000 because target called exit() +122 123 124 Exiting @ tick 250962019000 because target called exit() diff --git a/tests/long/70.twolf/ref/x86/linux/simple-timing/stats.txt b/tests/long/70.twolf/ref/x86/linux/simple-timing/stats.txt index d0361bdaa2..96e63da4be 100644 --- a/tests/long/70.twolf/ref/x86/linux/simple-timing/stats.txt +++ b/tests/long/70.twolf/ref/x86/linux/simple-timing/stats.txt @@ -1,84 +1,84 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 489241 # Simulator instruction rate (inst/s) -host_mem_usage 228040 # Number of bytes of host memory used -host_seconds 448.51 # Real time elapsed on the host -host_tick_rate 559541126 # Simulator tick rate (ticks/s) +host_inst_rate 894535 # Simulator instruction rate (inst/s) +host_mem_usage 201656 # Number of bytes of host memory used +host_seconds 245.30 # Real time elapsed on the host +host_tick_rate 1023073835 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks sim_insts 219430973 # Number of instructions simulated sim_seconds 0.250962 # Number of seconds simulated -sim_ticks 250961789000 # Number of ticks simulated +sim_ticks 250962019000 # Number of ticks simulated system.cpu.dcache.ReadReq_accesses 56682001 # number of ReadReq accesses(hits+misses) -system.cpu.dcache.ReadReq_avg_miss_latency 55873.040752 # average ReadReq miss latency -system.cpu.dcache.ReadReq_avg_mshr_miss_latency 52873.040752 # average ReadReq mshr miss latency -system.cpu.dcache.ReadReq_hits 56681682 # number of ReadReq hits -system.cpu.dcache.ReadReq_miss_latency 17823500 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_avg_miss_latency 55228.395062 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 52226.851852 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 56681677 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 17894000 # number of ReadReq miss cycles system.cpu.dcache.ReadReq_miss_rate 0.000006 # miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_misses 319 # number of ReadReq misses -system.cpu.dcache.ReadReq_mshr_miss_latency 16866500 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_misses 324 # number of ReadReq misses +system.cpu.dcache.ReadReq_mshr_miss_latency 16921500 # number of ReadReq MSHR miss cycles system.cpu.dcache.ReadReq_mshr_miss_rate 0.000006 # mshr miss rate for ReadReq accesses -system.cpu.dcache.ReadReq_mshr_misses 319 # number of ReadReq MSHR misses +system.cpu.dcache.ReadReq_mshr_misses 324 # number of ReadReq MSHR misses system.cpu.dcache.WriteReq_accesses 20515729 # number of WriteReq accesses(hits+misses) system.cpu.dcache.WriteReq_avg_miss_latency 56000 # average WriteReq miss latency system.cpu.dcache.WriteReq_avg_mshr_miss_latency 53000 # average WriteReq mshr miss latency -system.cpu.dcache.WriteReq_hits 20514128 # number of WriteReq hits -system.cpu.dcache.WriteReq_miss_latency 89656000 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_hits 20514125 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 89824000 # number of WriteReq miss cycles system.cpu.dcache.WriteReq_miss_rate 0.000078 # miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_misses 1601 # number of WriteReq misses -system.cpu.dcache.WriteReq_mshr_miss_latency 84853000 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_misses 1604 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 85012000 # number of WriteReq MSHR miss cycles system.cpu.dcache.WriteReq_mshr_miss_rate 0.000078 # mshr miss rate for WriteReq accesses -system.cpu.dcache.WriteReq_mshr_misses 1601 # number of WriteReq MSHR misses +system.cpu.dcache.WriteReq_mshr_misses 1604 # number of WriteReq MSHR misses system.cpu.dcache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.dcache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.dcache.avg_refs 40758.097149 # Average number of references to valid blocks. +system.cpu.dcache.avg_refs 40586.660358 # Average number of references to valid blocks. system.cpu.dcache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.dcache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.dcache.cache_copies 0 # number of cache copies performed system.cpu.dcache.demand_accesses 77197730 # number of demand (read+write) accesses -system.cpu.dcache.demand_avg_miss_latency 55978.906250 # average overall miss latency -system.cpu.dcache.demand_avg_mshr_miss_latency 52978.906250 # average overall mshr miss latency -system.cpu.dcache.demand_hits 77195810 # number of demand (read+write) hits -system.cpu.dcache.demand_miss_latency 107479500 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_avg_miss_latency 55870.331950 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 52870.072614 # average overall mshr miss latency +system.cpu.dcache.demand_hits 77195802 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 107718000 # number of demand (read+write) miss cycles system.cpu.dcache.demand_miss_rate 0.000025 # miss rate for demand accesses -system.cpu.dcache.demand_misses 1920 # number of demand (read+write) misses +system.cpu.dcache.demand_misses 1928 # number of demand (read+write) misses system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.dcache.demand_mshr_miss_latency 101719500 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_latency 101933500 # number of demand (read+write) MSHR miss cycles system.cpu.dcache.demand_mshr_miss_rate 0.000025 # mshr miss rate for demand accesses -system.cpu.dcache.demand_mshr_misses 1920 # number of demand (read+write) MSHR misses +system.cpu.dcache.demand_mshr_misses 1928 # number of demand (read+write) MSHR misses system.cpu.dcache.fast_writes 0 # number of fast writes performed system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.dcache.overall_accesses 77197730 # number of overall (read+write) accesses -system.cpu.dcache.overall_avg_miss_latency 55978.906250 # average overall miss latency -system.cpu.dcache.overall_avg_mshr_miss_latency 52978.906250 # average overall mshr miss latency +system.cpu.dcache.overall_avg_miss_latency 55870.331950 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 52870.072614 # average overall mshr miss latency system.cpu.dcache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.dcache.overall_hits 77195810 # number of overall hits -system.cpu.dcache.overall_miss_latency 107479500 # number of overall miss cycles +system.cpu.dcache.overall_hits 77195802 # number of overall hits +system.cpu.dcache.overall_miss_latency 107718000 # number of overall miss cycles system.cpu.dcache.overall_miss_rate 0.000025 # miss rate for overall accesses -system.cpu.dcache.overall_misses 1920 # number of overall misses +system.cpu.dcache.overall_misses 1928 # number of overall misses system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.dcache.overall_mshr_miss_latency 101719500 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_latency 101933500 # number of overall MSHR miss cycles system.cpu.dcache.overall_mshr_miss_rate 0.000025 # mshr miss rate for overall accesses -system.cpu.dcache.overall_mshr_misses 1920 # number of overall MSHR misses +system.cpu.dcache.overall_mshr_misses 1928 # number of overall MSHR misses system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses -system.cpu.dcache.replacements 27 # number of replacements -system.cpu.dcache.sampled_refs 1894 # Sample count of references to valid blocks. +system.cpu.dcache.replacements 40 # number of replacements +system.cpu.dcache.sampled_refs 1902 # Sample count of references to valid blocks. system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.dcache.tagsinuse 1362.582472 # Cycle average of tags in use -system.cpu.dcache.total_refs 77195836 # Total number of references to valid blocks. +system.cpu.dcache.tagsinuse 1361.446792 # Cycle average of tags in use +system.cpu.dcache.total_refs 77195828 # Total number of references to valid blocks. system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit. -system.cpu.dcache.writebacks 2 # number of writebacks +system.cpu.dcache.writebacks 7 # number of writebacks system.cpu.icache.ReadReq_accesses 173494375 # number of ReadReq accesses(hits+misses) -system.cpu.icache.ReadReq_avg_miss_latency 39420.962931 # average ReadReq miss latency -system.cpu.icache.ReadReq_avg_mshr_miss_latency 36414.252237 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_avg_miss_latency 39420.856412 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 36414.145718 # average ReadReq mshr miss latency system.cpu.icache.ReadReq_hits 173489681 # number of ReadReq hits -system.cpu.icache.ReadReq_miss_latency 185042000 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_latency 185041500 # number of ReadReq miss cycles system.cpu.icache.ReadReq_miss_rate 0.000027 # miss rate for ReadReq accesses system.cpu.icache.ReadReq_misses 4694 # number of ReadReq misses -system.cpu.icache.ReadReq_mshr_miss_latency 170928500 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_latency 170928000 # number of ReadReq MSHR miss cycles system.cpu.icache.ReadReq_mshr_miss_rate 0.000027 # mshr miss rate for ReadReq accesses system.cpu.icache.ReadReq_mshr_misses 4694 # number of ReadReq MSHR misses system.cpu.icache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked @@ -90,29 +90,29 @@ system.cpu.icache.blocked_cycles::no_mshrs 0 # system.cpu.icache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.icache.cache_copies 0 # number of cache copies performed system.cpu.icache.demand_accesses 173494375 # number of demand (read+write) accesses -system.cpu.icache.demand_avg_miss_latency 39420.962931 # average overall miss latency -system.cpu.icache.demand_avg_mshr_miss_latency 36414.252237 # average overall mshr miss latency +system.cpu.icache.demand_avg_miss_latency 39420.856412 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 36414.145718 # average overall mshr miss latency system.cpu.icache.demand_hits 173489681 # number of demand (read+write) hits -system.cpu.icache.demand_miss_latency 185042000 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_latency 185041500 # number of demand (read+write) miss cycles system.cpu.icache.demand_miss_rate 0.000027 # miss rate for demand accesses system.cpu.icache.demand_misses 4694 # number of demand (read+write) misses system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.icache.demand_mshr_miss_latency 170928500 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_latency 170928000 # number of demand (read+write) MSHR miss cycles system.cpu.icache.demand_mshr_miss_rate 0.000027 # mshr miss rate for demand accesses system.cpu.icache.demand_mshr_misses 4694 # number of demand (read+write) MSHR misses system.cpu.icache.fast_writes 0 # number of fast writes performed system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate system.cpu.icache.overall_accesses 173494375 # number of overall (read+write) accesses -system.cpu.icache.overall_avg_miss_latency 39420.962931 # average overall miss latency -system.cpu.icache.overall_avg_mshr_miss_latency 36414.252237 # average overall mshr miss latency +system.cpu.icache.overall_avg_miss_latency 39420.856412 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 36414.145718 # average overall mshr miss latency system.cpu.icache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency system.cpu.icache.overall_hits 173489681 # number of overall hits -system.cpu.icache.overall_miss_latency 185042000 # number of overall miss cycles +system.cpu.icache.overall_miss_latency 185041500 # number of overall miss cycles system.cpu.icache.overall_miss_rate 0.000027 # miss rate for overall accesses system.cpu.icache.overall_misses 4694 # number of overall misses system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.icache.overall_mshr_miss_latency 170928500 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_latency 170928000 # number of overall MSHR miss cycles system.cpu.icache.overall_mshr_miss_rate 0.000027 # mshr miss rate for overall accesses system.cpu.icache.overall_mshr_misses 4694 # number of overall MSHR misses system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles @@ -120,29 +120,29 @@ system.cpu.icache.overall_mshr_uncacheable_misses 0 system.cpu.icache.replacements 2836 # number of replacements system.cpu.icache.sampled_refs 4694 # Sample count of references to valid blocks. system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.icache.tagsinuse 1455.283776 # Cycle average of tags in use +system.cpu.icache.tagsinuse 1455.283940 # Cycle average of tags in use system.cpu.icache.total_refs 173489681 # Total number of references to valid blocks. system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.icache.writebacks 0 # number of writebacks system.cpu.idle_fraction 0 # Percentage of idle cycles -system.cpu.l2cache.ReadExReq_accesses 1575 # number of ReadExReq accesses(hits+misses) +system.cpu.l2cache.ReadExReq_accesses 1578 # number of ReadExReq accesses(hits+misses) system.cpu.l2cache.ReadExReq_avg_miss_latency 52000 # average ReadExReq miss latency system.cpu.l2cache.ReadExReq_avg_mshr_miss_latency 40000 # average ReadExReq mshr miss latency -system.cpu.l2cache.ReadExReq_miss_latency 81900000 # number of ReadExReq miss cycles +system.cpu.l2cache.ReadExReq_miss_latency 82056000 # number of ReadExReq miss cycles system.cpu.l2cache.ReadExReq_miss_rate 1 # miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_misses 1575 # number of ReadExReq misses -system.cpu.l2cache.ReadExReq_mshr_miss_latency 63000000 # number of ReadExReq MSHR miss cycles +system.cpu.l2cache.ReadExReq_misses 1578 # number of ReadExReq misses +system.cpu.l2cache.ReadExReq_mshr_miss_latency 63120000 # number of ReadExReq MSHR miss cycles system.cpu.l2cache.ReadExReq_mshr_miss_rate 1 # mshr miss rate for ReadExReq accesses -system.cpu.l2cache.ReadExReq_mshr_misses 1575 # number of ReadExReq MSHR misses -system.cpu.l2cache.ReadReq_accesses 5013 # number of ReadReq accesses(hits+misses) -system.cpu.l2cache.ReadReq_avg_miss_latency 52005.066498 # average ReadReq miss latency +system.cpu.l2cache.ReadExReq_mshr_misses 1578 # number of ReadExReq MSHR misses +system.cpu.l2cache.ReadReq_accesses 5018 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 52004.908170 # average ReadReq miss latency system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 40000 # average ReadReq mshr miss latency -system.cpu.l2cache.ReadReq_hits 1855 # number of ReadReq hits -system.cpu.l2cache.ReadReq_miss_latency 164232000 # number of ReadReq miss cycles -system.cpu.l2cache.ReadReq_miss_rate 0.629962 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_hits 1860 # number of ReadReq hits +system.cpu.l2cache.ReadReq_miss_latency 164231500 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.629334 # miss rate for ReadReq accesses system.cpu.l2cache.ReadReq_misses 3158 # number of ReadReq misses system.cpu.l2cache.ReadReq_mshr_miss_latency 126320000 # number of ReadReq MSHR miss cycles -system.cpu.l2cache.ReadReq_mshr_miss_rate 0.629962 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.629334 # mshr miss rate for ReadReq accesses system.cpu.l2cache.ReadReq_mshr_misses 3158 # number of ReadReq MSHR misses system.cpu.l2cache.UpgradeReq_accesses 26 # number of UpgradeReq accesses(hits+misses) system.cpu.l2cache.UpgradeReq_avg_miss_latency 52000 # average UpgradeReq miss latency @@ -153,53 +153,53 @@ system.cpu.l2cache.UpgradeReq_misses 26 # nu system.cpu.l2cache.UpgradeReq_mshr_miss_latency 1040000 # number of UpgradeReq MSHR miss cycles system.cpu.l2cache.UpgradeReq_mshr_miss_rate 1 # mshr miss rate for UpgradeReq accesses system.cpu.l2cache.UpgradeReq_mshr_misses 26 # number of UpgradeReq MSHR misses -system.cpu.l2cache.Writeback_accesses 2 # number of Writeback accesses(hits+misses) -system.cpu.l2cache.Writeback_hits 2 # number of Writeback hits +system.cpu.l2cache.Writeback_accesses 7 # number of Writeback accesses(hits+misses) +system.cpu.l2cache.Writeback_hits 7 # number of Writeback hits system.cpu.l2cache.avg_blocked_cycles::no_mshrs no_value # average number of cycles each access was blocked system.cpu.l2cache.avg_blocked_cycles::no_targets no_value # average number of cycles each access was blocked -system.cpu.l2cache.avg_refs 0.591895 # Average number of references to valid blocks. +system.cpu.l2cache.avg_refs 0.593112 # Average number of references to valid blocks. system.cpu.l2cache.blocked::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_mshrs 0 # number of cycles access was blocked system.cpu.l2cache.blocked_cycles::no_targets 0 # number of cycles access was blocked system.cpu.l2cache.cache_copies 0 # number of cache copies performed -system.cpu.l2cache.demand_accesses 6588 # number of demand (read+write) accesses -system.cpu.l2cache.demand_avg_miss_latency 52003.380520 # average overall miss latency +system.cpu.l2cache.demand_accesses 6596 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 52003.272804 # average overall miss latency system.cpu.l2cache.demand_avg_mshr_miss_latency 40000 # average overall mshr miss latency -system.cpu.l2cache.demand_hits 1855 # number of demand (read+write) hits -system.cpu.l2cache.demand_miss_latency 246132000 # number of demand (read+write) miss cycles -system.cpu.l2cache.demand_miss_rate 0.718427 # miss rate for demand accesses -system.cpu.l2cache.demand_misses 4733 # number of demand (read+write) misses +system.cpu.l2cache.demand_hits 1860 # number of demand (read+write) hits +system.cpu.l2cache.demand_miss_latency 246287500 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.718011 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 4736 # number of demand (read+write) misses system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits -system.cpu.l2cache.demand_mshr_miss_latency 189320000 # number of demand (read+write) MSHR miss cycles -system.cpu.l2cache.demand_mshr_miss_rate 0.718427 # mshr miss rate for demand accesses -system.cpu.l2cache.demand_mshr_misses 4733 # number of demand (read+write) MSHR misses +system.cpu.l2cache.demand_mshr_miss_latency 189440000 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.718011 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 4736 # number of demand (read+write) MSHR misses system.cpu.l2cache.fast_writes 0 # number of fast writes performed system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate -system.cpu.l2cache.overall_accesses 6588 # number of overall (read+write) accesses -system.cpu.l2cache.overall_avg_miss_latency 52003.380520 # average overall miss latency +system.cpu.l2cache.overall_accesses 6596 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 52003.272804 # average overall miss latency system.cpu.l2cache.overall_avg_mshr_miss_latency 40000 # average overall mshr miss latency system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no_value # average overall mshr uncacheable latency -system.cpu.l2cache.overall_hits 1855 # number of overall hits -system.cpu.l2cache.overall_miss_latency 246132000 # number of overall miss cycles -system.cpu.l2cache.overall_miss_rate 0.718427 # miss rate for overall accesses -system.cpu.l2cache.overall_misses 4733 # number of overall misses +system.cpu.l2cache.overall_hits 1860 # number of overall hits +system.cpu.l2cache.overall_miss_latency 246287500 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.718011 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 4736 # number of overall misses system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits -system.cpu.l2cache.overall_mshr_miss_latency 189320000 # number of overall MSHR miss cycles -system.cpu.l2cache.overall_mshr_miss_rate 0.718427 # mshr miss rate for overall accesses -system.cpu.l2cache.overall_mshr_misses 4733 # number of overall MSHR misses +system.cpu.l2cache.overall_mshr_miss_latency 189440000 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.718011 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 4736 # number of overall MSHR misses system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses system.cpu.l2cache.replacements 0 # number of replacements -system.cpu.l2cache.sampled_refs 3134 # Sample count of references to valid blocks. +system.cpu.l2cache.sampled_refs 3136 # Sample count of references to valid blocks. system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions -system.cpu.l2cache.tagsinuse 2033.146295 # Cycle average of tags in use -system.cpu.l2cache.total_refs 1855 # Total number of references to valid blocks. +system.cpu.l2cache.tagsinuse 2033.169065 # Cycle average of tags in use +system.cpu.l2cache.total_refs 1860 # Total number of references to valid blocks. system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit. system.cpu.l2cache.writebacks 0 # number of writebacks system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 501923578 # number of cpu cycles simulated +system.cpu.numCycles 501924038 # number of cpu cycles simulated system.cpu.num_insts 219430973 # Number of instructions executed system.cpu.num_refs 77165298 # Number of memory references system.cpu.workload.PROG:num_syscalls 400 # Number of system calls From 53086dfefe2796497724daaa7d5d1d3d85a8a636 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 22:49:57 -0800 Subject: [PATCH 094/160] X86: Make x86 use PREFETCH instead of PF_EXCLUSIVE. --- src/arch/x86/isa/microops/ldstop.isa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 912aa3511d..afe1ead594 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -157,7 +157,7 @@ def template MicroLoadExecute {{ if (fault == NoFault) { %(code)s; - } else if (memFlags & Request::PF_EXCLUSIVE) { + } else if (memFlags & Request::PREFETCH) { // For prefetches, ignore any faults/exceptions. return NoFault; } @@ -374,7 +374,7 @@ let {{ if atCPL0: self.memFlags += " | (CPL0FlagBit << FlagShift)" if prefetch: - self.memFlags += " | Request::PF_EXCLUSIVE" + self.memFlags += " | Request::PREFETCH" self.memFlags += " | (machInst.legacy.addr ? " + \ "(AddrSizeFlagBit << FlagShift) : 0)" From 44e912c6bd8828a6a3774c1fa54a1f4689383243 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 22:49:57 -0800 Subject: [PATCH 095/160] X86: Explain what really didn't work with unmapped addresses in SE mode. --- src/arch/x86/tlb.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 5280b9ba86..0d69d05c94 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -632,12 +632,22 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, Process *p = tc->getProcessPtr(); TlbEntry newEntry; bool success = p->pTable->lookup(vaddr, newEntry); - if(!success && mode != Execute) { + if (!success && mode != Execute) { p->checkAndAllocNextPage(vaddr); success = p->pTable->lookup(vaddr, newEntry); } - if(!success) { - panic("Tried to execute unmapped address %#x.\n", vaddr); + if (!success) { + const char *modeStr = ""; + if (mode == Execute) + modeStr = "execute"; + else if (mode == Read) + modeStr = "read"; + else if (mode == Write) + modeStr = "write"; + else + modeStr = "?"; + panic("Tried to %s unmapped address %#x.\n", + modeStr, vaddr); } else { Addr alignedVaddr = p->pTable->pageAlign(vaddr); DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, From bbbfdee2ed4feb5e8e448920e5d51701a2192ee1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 22:49:58 -0800 Subject: [PATCH 096/160] X86: Don't panic on faults on prefetches in SE mode. --- src/arch/x86/tlb.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 0d69d05c94..d7959da2c0 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -637,17 +637,21 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, success = p->pTable->lookup(vaddr, newEntry); } if (!success) { - const char *modeStr = ""; - if (mode == Execute) - modeStr = "execute"; - else if (mode == Read) - modeStr = "read"; - else if (mode == Write) - modeStr = "write"; - else - modeStr = "?"; - panic("Tried to %s unmapped address %#x.\n", - modeStr, vaddr); + if (req->isPrefetch()) { + return new PageFault(vaddr, true, mode, true, false); + } else { + const char *modeStr = ""; + if (mode == Execute) + modeStr = "execute"; + else if (mode == Read) + modeStr = "read"; + else if (mode == Write) + modeStr = "write"; + else + modeStr = "?"; + panic("Tried to %s unmapped address %#x.\n", + modeStr, vaddr); + } } else { Addr alignedVaddr = p->pTable->pageAlign(vaddr); DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, From 7da221ca82e5e64b98d9e86421fa653e2ad3e540 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 9 Nov 2009 10:02:55 -0500 Subject: [PATCH 097/160] syscall: missing initializer in getcwd call This one case was missed during the update to stack-based arguments. Without this fix, m5 will crash during a gwtcwd call, at least with X86. --- src/sim/syscall_emul.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 7cffffcf1c..4461e8b528 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -306,7 +306,7 @@ SyscallReturn getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { int result = 0; - int index; + int index = 0; Addr bufPtr = p->getSyscallArg(tc, index); unsigned long size = p->getSyscallArg(tc, index); BufferArg buf(bufPtr, size); From e81cc233a6fa82d2aec45bd9160db15df112f584 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 10 Nov 2009 11:18:23 -0500 Subject: [PATCH 098/160] X86: Remove double-cast in Cvtf2i micro-op This double cast led to rounding errors which caused some benchmarks to get the wrong values, most notably lucas which failed spectacularly due to CVTTSD2SI returning an off-by-one value. equake was also broken. --- src/arch/x86/isa/microops/mediaop.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa index 9c53fa0fbd..fa32583b08 100644 --- a/src/arch/x86/isa/microops/mediaop.isa +++ b/src/arch/x86/isa/microops/mediaop.isa @@ -1237,7 +1237,7 @@ let {{ } if (destSize == 4) { - argBits = (uint32_t)(float)arg; + argBits = (uint32_t)arg; } else { argBits = (uint64_t)arg; } From 53e27c0277a41ab1cae45d82fb4409f65cf660c3 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 10 Nov 2009 11:29:30 -0500 Subject: [PATCH 099/160] X86: Fix bugs in movd implementation. Unfortunately my implementation of the movd instruction had two bugs. In one case, when moving a 32-bit value into an xmm register, the lower half of the xmm register was not zero extended. The other case is that xmm was used instead of xmmlm as the source for a register move. My test case didn't notice this at first as it moved xmm0 to eax, which both have the same register number. --- src/arch/x86/isa/insts/general_purpose/data_transfer/move.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 7aee3fec1a..51f5ad23b5 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -357,7 +357,7 @@ def macroop MOVNTI_P_R { }; def macroop MOVD_XMM_R { - mov2fp xmml, regm, srcSize=dsz, destSize=dsz + mov2fp xmml, regm, srcSize=dsz, destSize=8 lfpimm xmmh, 0 }; @@ -373,7 +373,7 @@ def macroop MOVD_XMM_P { }; def macroop MOVD_R_XMM { - mov2int reg, xmml, size=dsz + mov2int reg, xmmlm, size=dsz }; def macroop MOVD_M_XMM { From 4779020e139c70355335729b504195a0e5009e7a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 20:19:55 -0800 Subject: [PATCH 100/160] ARM: Fix the integer register indexes. The PC indexes in the various register sets was defined in the section for unaliased registers which was throwing off the indexing. This moves those where they belong. Also, to make detecting accesses to the PC easier and because it's in the same place in all modes, the intRegForceUser function now passes it through as index 15. --- src/arch/arm/intregs.hh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 0c2fc5fbbb..15499601ac 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -63,31 +63,26 @@ enum IntRegIndex INTREG_SP_SVC = INTREG_R13_SVC, INTREG_R14_SVC, INTREG_LR_SVC = INTREG_R14_SVC, - INTREG_R15_SVC = INTREG_R15, INTREG_R13_MON, INTREG_SP_MON = INTREG_R13_MON, INTREG_R14_MON, INTREG_LR_MON = INTREG_R14_MON, - INTREG_R15_MON = INTREG_R15, INTREG_R13_ABT, INTREG_SP_ABT = INTREG_R13_ABT, INTREG_R14_ABT, INTREG_LR_ABT = INTREG_R14_ABT, - INTREG_R15_ABT = INTREG_R15, INTREG_R13_UND, INTREG_SP_UND = INTREG_R13_UND, INTREG_R14_UND, INTREG_LR_UND = INTREG_R14_UND, - INTREG_R15_UND = INTREG_R15, INTREG_R13_IRQ, INTREG_SP_IRQ = INTREG_R13_IRQ, INTREG_R14_IRQ, INTREG_LR_IRQ = INTREG_R14_IRQ, - INTREG_R15_IRQ = INTREG_R15, INTREG_R8_FIQ, INTREG_R9_FIQ, @@ -98,7 +93,6 @@ enum IntRegIndex INTREG_SP_FIQ = INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_LR_FIQ = INTREG_R14_FIQ, - INTREG_R15_FIQ = INTREG_R15, INTREG_ZERO, // Dummy zero reg since there has to be one. INTREG_UREG0, @@ -147,6 +141,7 @@ enum IntRegIndex INTREG_R11_SVC = INTREG_R11, INTREG_R12_SVC = INTREG_R12, INTREG_PC_SVC = INTREG_PC, + INTREG_R15_SVC = INTREG_R15, /* MON mode */ INTREG_R0_MON = INTREG_R0, @@ -163,6 +158,7 @@ enum IntRegIndex INTREG_R11_MON = INTREG_R11, INTREG_R12_MON = INTREG_R12, INTREG_PC_MON = INTREG_PC, + INTREG_R15_MON = INTREG_R15, /* ABT mode */ INTREG_R0_ABT = INTREG_R0, @@ -179,6 +175,7 @@ enum IntRegIndex INTREG_R11_ABT = INTREG_R11, INTREG_R12_ABT = INTREG_R12, INTREG_PC_ABT = INTREG_PC, + INTREG_R15_ABT = INTREG_R15, /* UND mode */ INTREG_R0_UND = INTREG_R0, @@ -195,6 +192,7 @@ enum IntRegIndex INTREG_R11_UND = INTREG_R11, INTREG_R12_UND = INTREG_R12, INTREG_PC_UND = INTREG_PC, + INTREG_R15_UND = INTREG_R15, /* IRQ mode */ INTREG_R0_IRQ = INTREG_R0, @@ -211,6 +209,7 @@ enum IntRegIndex INTREG_R11_IRQ = INTREG_R11, INTREG_R12_IRQ = INTREG_R12, INTREG_PC_IRQ = INTREG_PC, + INTREG_R15_IRQ = INTREG_R15, /* FIQ mode */ INTREG_R0_FIQ = INTREG_R0, @@ -222,6 +221,7 @@ enum IntRegIndex INTREG_R6_FIQ = INTREG_R6, INTREG_R7_FIQ = INTREG_R7, INTREG_PC_FIQ = INTREG_PC, + INTREG_R15_FIQ = INTREG_R15, }; typedef IntRegIndex IntRegMap[NUM_ARCH_INTREGS]; @@ -328,7 +328,8 @@ static inline IntRegIndex intRegForceUser(unsigned index) { assert(index < NUM_ARCH_INTREGS); - return (IntRegIndex)(index + NUM_INTREGS); + + return index == 15 ? (IntRegIndex)15 : (IntRegIndex)(index + NUM_INTREGS); } } From 2e28da5583814efe1e0a09718f6a674f983d12d1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 20:34:38 -0800 Subject: [PATCH 101/160] ARM: Implement fault classes. Implement some fault classes using the curriously recurring template pattern, similar to SPARCs. --- src/arch/arm/SConscript | 2 +- src/arch/arm/faults.cc | 536 ++++--------------------- src/arch/arm/faults.hh | 563 +++------------------------ src/arch/arm/isa.hh | 8 + src/arch/arm/isa/formats/unimp.isa | 2 +- src/arch/arm/isa/formats/unknown.isa | 2 +- src/arch/arm/isa_traits.hh | 2 + src/arch/arm/miscregs.hh | 37 +- src/arch/arm/utility.cc | 19 + 9 files changed, 192 insertions(+), 979 deletions(-) create mode 100644 src/arch/arm/utility.cc diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index 55ecabdc3b..f5fe1727c3 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -48,7 +48,7 @@ if env['TARGET_ISA'] == 'arm': SimObject('ArmTLB.py') TraceFlag('Arm') - + TraceFlag('Faults', "Trace Exceptions, interrupts, svc/swi") if env['FULL_SYSTEM']: #Insert Full-System Files Here pass diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 3d882c97f1..b7dd2d503b 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -26,488 +26,114 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Gabe Black - * Stephen Hines + * Authors: Ali Saidi + * Gabe Black */ #include "arch/arm/faults.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "base/trace.hh" -#if !FULL_SYSTEM -#include "sim/process.hh" -#include "mem/page_table.hh" -#endif namespace ArmISA { -FaultName MachineCheckFault::_name = "Machine Check"; -FaultVect MachineCheckFault::_vect = 0x0401; -FaultStat MachineCheckFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"reset", 0x00, MODE_SVC, 0, 0, true, true}; -FaultName AlignmentFault::_name = "Alignment"; -FaultVect AlignmentFault::_vect = 0x0301; -FaultStat AlignmentFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ; -FaultName ResetFault::_name = "Reset Fault"; -#if FULL_SYSTEM -FaultVect ResetFault::_vect = 0xBFC00000; -#else -FaultVect ResetFault::_vect = 0x001; -#endif -FaultStat ResetFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false}; -FaultName AddressErrorFault::_name = "Address Error"; -FaultVect AddressErrorFault::_vect = 0x0180; -FaultStat AddressErrorFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false}; -FaultName StoreAddressErrorFault::_name = "Store Address Error"; -FaultVect StoreAddressErrorFault::_vect = 0x0180; -FaultStat StoreAddressErrorFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false}; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false}; -FaultName SystemCallFault::_name = "Syscall"; -FaultVect SystemCallFault::_vect = 0x0180; -FaultStat SystemCallFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true}; -FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault"; -FaultVect CoprocessorUnusableFault::_vect = 0x180; -FaultStat CoprocessorUnusableFault::_count; +Addr +ArmFaultBase::getVector(ThreadContext *tc) +{ + // ARM ARM B1-3 -FaultName ReservedInstructionFault::_name = "Reserved Instruction Fault"; -FaultVect ReservedInstructionFault::_vect = 0x0180; -FaultStat ReservedInstructionFault::_count; + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + + // panic if SCTLR.VE because I have no idea what to do with vectored + // interrupts + assert(!sctlr.ve); + + if (!sctlr.v) + return offset(); + return offset() + HighVecs; -FaultName ThreadFault::_name = "Thread Fault"; -FaultVect ThreadFault::_vect = 0x00F1; -FaultStat ThreadFault::_count; - - -FaultName ArithmeticFault::_name = "Arithmetic Overflow Exception"; -FaultVect ArithmeticFault::_vect = 0x180; -FaultStat ArithmeticFault::_count; - -FaultName UnimplementedOpcodeFault::_name = "opdec"; -FaultVect UnimplementedOpcodeFault::_vect = 0x0481; -FaultStat UnimplementedOpcodeFault::_count; - -FaultName InterruptFault::_name = "interrupt"; -FaultVect InterruptFault::_vect = 0x0180; -FaultStat InterruptFault::_count; - -FaultName TrapFault::_name = "Trap"; -FaultVect TrapFault::_vect = 0x0180; -FaultStat TrapFault::_count; - -FaultName BreakpointFault::_name = "Breakpoint"; -FaultVect BreakpointFault::_vect = 0x0180; -FaultStat BreakpointFault::_count; - - -FaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)"; -FaultVect ItbInvalidFault::_vect = 0x0180; -FaultStat ItbInvalidFault::_count; - -FaultName ItbPageFault::_name = "itbmiss"; -FaultVect ItbPageFault::_vect = 0x0181; -FaultStat ItbPageFault::_count; - -FaultName ItbMissFault::_name = "itbmiss"; -FaultVect ItbMissFault::_vect = 0x0181; -FaultStat ItbMissFault::_count; - -FaultName ItbAcvFault::_name = "iaccvio"; -FaultVect ItbAcvFault::_vect = 0x0081; -FaultStat ItbAcvFault::_count; - -FaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)"; -FaultVect ItbRefillFault::_vect = 0x0180; -FaultStat ItbRefillFault::_count; - -FaultName NDtbMissFault::_name = "dtb_miss_single"; -FaultVect NDtbMissFault::_vect = 0x0201; -FaultStat NDtbMissFault::_count; - -FaultName PDtbMissFault::_name = "dtb_miss_double"; -FaultVect PDtbMissFault::_vect = 0x0281; -FaultStat PDtbMissFault::_count; - -FaultName DtbPageFault::_name = "dfault"; -FaultVect DtbPageFault::_vect = 0x0381; -FaultStat DtbPageFault::_count; - -FaultName DtbAcvFault::_name = "dfault"; -FaultVect DtbAcvFault::_vect = 0x0381; -FaultStat DtbAcvFault::_count; - -FaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)"; -FaultVect DtbInvalidFault::_vect = 0x0180; -FaultStat DtbInvalidFault::_count; - -FaultName DtbRefillFault::_name = "TLB Refill Exception (Store)"; -FaultVect DtbRefillFault::_vect = 0x0180; -FaultStat DtbRefillFault::_count; - -FaultName TLBModifiedFault::_name = "TLB Modified Exception"; -FaultVect TLBModifiedFault::_vect = 0x0180; -FaultStat TLBModifiedFault::_count; - -FaultName FloatEnableFault::_name = "float_enable_fault"; -FaultVect FloatEnableFault::_vect = 0x0581; -FaultStat FloatEnableFault::_count; - -FaultName IntegerOverflowFault::_name = "Integer Overflow Fault"; -FaultVect IntegerOverflowFault::_vect = 0x0501; -FaultStat IntegerOverflowFault::_count; - -FaultName DspStateDisabledFault::_name = "DSP Disabled Fault"; -FaultVect DspStateDisabledFault::_vect = 0x001a; -FaultStat DspStateDisabledFault::_count; +} #if FULL_SYSTEM -void ArmFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc) + +void +ArmFaultBase::invoke(ThreadContext *tc) { - tc->setPC(HandlerBase); - tc->setNextPC(HandlerBase+sizeof(MachInst)); - tc->setNextNPC(HandlerBase+2*sizeof(MachInst)); + // ARM ARM B1.6.3 + FaultBase::invoke(tc); + countStat()++; + + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); + CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) | + tc->readIntReg(INTREG_CONDCODES); + + + cpsr.mode = nextMode(); + cpsr.it1 = cpsr.it2 = 0; + cpsr.j = 0; + + if (sctlr.te) + cpsr.t = 1; + cpsr.a = cpsr.a | abortDisable(); + cpsr.f = cpsr.f | fiqDisable(); + cpsr.i = 1; + tc->setMiscReg(MISCREG_CPSR, cpsr); + tc->setIntReg(INTREG_LR, tc->readPC() + + (saved_cpsr.t ? thumbPcOffset() : armPcOffset())); + + switch (nextMode()) { + case MODE_FIQ: + tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); + break; + case MODE_IRQ: + tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); + break; + case MODE_SVC: + tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); + break; + case MODE_UNDEFINED: + tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); + break; + case MODE_ABORT: + tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); + break; + default: + panic("unknown Mode\n"); + } + + DPRINTF(Faults, "Invoking Fault: %s cpsr: %#x PC: %#x lr: %#x\n", name(), cpsr, + tc->readPC(), tc->readIntReg(INTREG_LR)); + tc->setPC(getVector(tc)); + tc->setNextPC(getVector(tc) + cpsr.t ? 2 : 4 ); } - -void ArmFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode) -{ - // modify SRS Ctl - Save CSS, put ESS into CSS - MiscReg stat = tc->readMiscReg(ArmISA::Status); - if(bits(stat,Status_EXL) != 1 && bits(stat,Status_BEV) != 1) - { - // SRS Ctl is modified only if Status_EXL and Status_BEV are not set - MiscReg srs = tc->readMiscReg(ArmISA::SRSCtl); - uint8_t CSS,ESS; - CSS = bits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO); - ESS = bits(srs,SRSCtl_ESS_HI,SRSCtl_ESS_LO); - // Move CSS to PSS - replaceBits(srs,SRSCtl_PSS_HI,SRSCtl_PSS_LO,CSS); - // Move ESS to CSS - replaceBits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO,ESS); - tc->setMiscRegNoEffect(ArmISA::SRSCtl,srs); - //tc->setShadowSet(ESS); - } - - // set EXL bit (don't care if it is already set!) - replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1); - tc->setMiscRegNoEffect(ArmISA::Status,stat); - - // write EPC - // warn("Set EPC to %x\n",tc->readPC()); - // CHECK ME or FIXME or FIX ME or POSSIBLE HACK - // Check to see if the exception occurred in the branch delay slot - DPRINTF(Arm,"PC: %x, NextPC: %x, NNPC: %x\n",tc->readPC(),tc->readNextPC(),tc->readNextNPC()); - int C_BD=0; - if(tc->readPC() + sizeof(MachInst) != tc->readNextPC()){ - tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()-sizeof(MachInst)); - // In the branch delay slot? set CAUSE_31 - C_BD = 1; - } else { - tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()); - // In the branch delay slot? reset CAUSE_31 - C_BD = 0; - } - - // Set Cause_EXCCODE field - MiscReg cause = tc->readMiscReg(ArmISA::Cause); - replaceBits(cause,Cause_EXCCODE_HI,Cause_EXCCODE_LO,ExcCode); - replaceBits(cause,Cause_BD_HI,Cause_BD_LO,C_BD); - replaceBits(cause,Cause_CE_HI,Cause_CE_LO,0); - tc->setMiscRegNoEffect(ArmISA::Cause,cause); - -} - -void ArithmeticFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0xC); - - // Set new PC - Addr HandlerBase; - MiscReg stat = tc->readMiscReg(ArmISA::Status); - // Here, the handler is dependent on BEV, which is not modified by setExceptionState() - if(bits(stat,Status_BEV)==0){ // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); - }else{ - HandlerBase = 0xBFC00200; - } - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); -} - -void StoreAddressErrorFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x5); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void TrapFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - // warn("%s encountered.\n", name()); - setExceptionState(tc,0xD); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); -} - -void BreakpointFault::invoke(ThreadContext *tc) -{ - setExceptionState(tc,0x9); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void DtbInvalidFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - // warn("%s encountered.\n", name()); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - setExceptionState(tc,0x3); - - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); -} - -void AddressErrorFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x4); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); -} - -void ItbInvalidFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x2); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - DPRINTF(Arm,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); -} - -void ItbRefillFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered (%x).\n", name(),BadVAddr); - Addr HandlerBase; - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - MiscReg stat = tc->readMiscReg(ArmISA::Status); - // Since handler depends on EXL bit, must check EXL bit before setting it!! - if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - }else{ - HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000 - } - - setExceptionState(tc,0x2); - setHandlerPC(HandlerBase,tc); -} - -void DtbRefillFault::invoke(ThreadContext *tc) -{ - // Set new PC - DPRINTF(Arm,"%s encountered.\n", name()); - Addr HandlerBase; - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - MiscReg stat = tc->readMiscReg(ArmISA::Status); - // Since handler depends on EXL bit, must check EXL bit before setting it!! - if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - }else{ - HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000 - } - - - setExceptionState(tc,0x3); - - setHandlerPC(HandlerBase,tc); -} - -void TLBModifiedFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setExceptionState(tc,0x1); - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void SystemCallFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x8); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void InterruptFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x0A); - Addr HandlerBase; - - - uint8_t IV = bits(tc->readMiscRegNoEffect(ArmISA::Cause),Cause_IV); - if (IV)// Offset 200 for release 2 - HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(ArmISA::EBase); - else//Ofset at 180 for release 1 - HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); - - setHandlerPC(HandlerBase,tc); -#endif -} - #endif // FULL_SYSTEM -void ResetFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - /* All reset activity must be invoked from here */ - tc->setPC(vect()); - tc->setNextPC(vect()+sizeof(MachInst)); - tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst)); - DPRINTF(Arm,"(%x) - ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC()); -#endif +// return via SUBS pc, lr, xxx; rfe, movs, ldm - // Set Coprocessor 1 (Floating Point) To Usable - //tc->setMiscReg(ArmISA::Status, ArmISA::Status | 0x20000000); -} -void ReservedInstructionFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x0A); - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); -#else - panic("%s encountered.\n", name()); -#endif -} - -void ThreadFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - panic("%s encountered.\n", name()); -} - -void DspStateDisabledFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - panic("%s encountered.\n", name()); -} - -void CoprocessorUnusableFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0xb); - /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */ - MiscReg cause = tc->readMiscReg(ArmISA::Cause); - replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID); - tc->setMiscRegNoEffect(ArmISA::Cause,cause); - - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - - // warn("Status: %x, Cause: %x\n",tc->readMiscReg(ArmISA::Status),tc->readMiscReg(ArmISA::Cause)); -#else - warn("%s (CP%d) encountered.\n", name(), coProcID); -#endif -} } // namespace ArmISA diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh index 28ecd75916..7f8aa66b66 100644 --- a/src/arch/arm/faults.hh +++ b/src/arch/arm/faults.hh @@ -26,548 +26,79 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Gabe Black - * Stephen Hines + * Authors: Ali Saidi + * Gabe Black */ #ifndef __ARM_FAULTS_HH__ #define __ARM_FAULTS_HH__ +#include "arch/arm/types.hh" +#include "config/full_system.hh" #include "sim/faults.hh" // The design of the "name" and "vect" functions is in sim/faults.hh namespace ArmISA { -typedef const Addr FaultVect; +typedef const Addr FaultOffset; -class ArmFault : public FaultBase +class ArmFaultBase : public FaultBase { protected: - virtual bool skipFaultingInstruction() {return false;} - virtual bool setRestartAddress() {return true;} + Addr getVector(ThreadContext *tc); + public: - Addr BadVAddr; - Addr EntryHi_Asid; - Addr EntryHi_VPN2; - Addr EntryHi_VPN2X; - Addr Context_BadVPN2; + struct FaultVals + { + const FaultName name; + const FaultOffset offset; + const OperatingMode nextMode; + const uint8_t armPcOffset; + const uint8_t thumbPcOffset; + const bool abortDisable; + const bool fiqDisable; + FaultStat count; + }; + #if FULL_SYSTEM - void invoke(ThreadContext * tc) {}; - void setExceptionState(ThreadContext *,uint8_t); - void setHandlerPC(Addr,ThreadContext *); + void invoke(ThreadContext *tc); #endif - virtual FaultVect vect() = 0; - virtual FaultStat & countStat() = 0; + virtual FaultStat& countStat() = 0; + virtual FaultOffset offset() = 0; + virtual OperatingMode nextMode() = 0; + virtual uint8_t armPcOffset() = 0; + virtual uint8_t thumbPcOffset() = 0; + virtual bool abortDisable() = 0; + virtual bool fiqDisable() = 0; }; -class MachineCheckFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isMachineCheckFault() {return true;} -}; - -class NonMaskableInterrupt : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isNonMaskableInterrupt() {return true;} -}; - -class AlignmentFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isAlignmentFault() {return true;} -}; - -class AddressErrorFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; -class StoreAddressErrorFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; -class UnimplementedOpcodeFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - - -class TLBRefillIFetchFault : public ArmFault -{ - private: - Addr vaddr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; -class TLBInvalidIFetchFault : public ArmFault -{ - private: - Addr vaddr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class NDtbMissFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class PDtbMissFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class DtbPageFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class DtbAcvFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class CacheErrorFault : public ArmFault -{ - private: - Addr vaddr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - - - - -static inline Fault genMachineCheckFault() -{ - return new MachineCheckFault; -} - -static inline Fault genAlignmentFault() -{ - return new AlignmentFault; -} - -class ResetFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); - -}; -class SystemCallFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class SoftResetFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; -class DebugSingleStep : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; -class DebugInterrupt : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class CoprocessorUnusableFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - int coProcID; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); - CoprocessorUnusableFault(int _procid){ coProcID = _procid;} -}; - -class ReservedInstructionFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class ThreadFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - - -class ArithmeticFault : public ArmFault +template +class ArmFault : public ArmFaultBase { protected: - bool skipFaultingInstruction() {return true;} - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; + static FaultVals vals; + public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif + FaultName name() const { return vals.name; } + FaultStat & countStat() {return vals.count;} + FaultOffset offset() { return vals.offset; } + OperatingMode nextMode() { return vals.nextMode; } + uint8_t armPcOffset() { return vals.armPcOffset; } + uint8_t thumbPcOffset() { return vals.thumbPcOffset; } + bool abortDisable() { return vals.abortDisable; } + bool fiqDisable() { return vals.fiqDisable; } }; -class InterruptFault : public ArmFault -{ - protected: - bool setRestartAddress() {return false;} - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif +class Reset : public ArmFault {}; +class UndefinedInstruction : public ArmFault {}; +class SupervisorCall : public ArmFault {}; +class PrefetchAbort : public ArmFault {}; +class DataAbort : public ArmFault {}; +class Interrupt : public ArmFault {}; +class FastInterrupt : public ArmFault {}; - //void invoke(ThreadContext * tc); -}; - -class TrapFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class BreakpointFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class ItbRefillFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; -class DtbRefillFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class ItbPageFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class ItbInvalidFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; -class TLBModifiedFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; - -class DtbInvalidFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; - -class FloatEnableFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class ItbMissFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class ItbAcvFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class IntegerOverflowFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class DspStateDisabledFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; } // ArmISA namespace diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index a4a328614e..a270f046bf 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -85,6 +85,14 @@ namespace ArmISA cpsr.mode = MODE_USER; miscRegs[MISCREG_CPSR] = cpsr; updateRegMap(cpsr); + + SCTLR sctlr = 0; + sctlr.nmfi = 1; + sctlr.rao1 = 1; + sctlr.rao2 = 1; + sctlr.rao3 = 1; + sctlr.rao4 = 1; + //XXX We need to initialize the rest of the state. } diff --git a/src/arch/arm/isa/formats/unimp.isa b/src/arch/arm/isa/formats/unimp.isa index c82bb41c63..6909c3f859 100644 --- a/src/arch/arm/isa/formats/unimp.isa +++ b/src/arch/arm/isa/formats/unimp.isa @@ -115,7 +115,7 @@ output exec {{ panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE, inst2string(machInst)); - return new UnimplementedOpcodeFault; + return new UnimpFault("Unimplemented Instruction"); } Fault diff --git a/src/arch/arm/isa/formats/unknown.isa b/src/arch/arm/isa/formats/unknown.isa index 2ad7a2506f..97a0caa6bb 100644 --- a/src/arch/arm/isa/formats/unknown.isa +++ b/src/arch/arm/isa/formats/unknown.isa @@ -74,7 +74,7 @@ output exec {{ { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst)); - return new UnimplementedOpcodeFault; + return new UnimpFault("Unimplemented Instruction"); } }}; diff --git a/src/arch/arm/isa_traits.hh b/src/arch/arm/isa_traits.hh index 542174b6b7..91c51c46b3 100644 --- a/src/arch/arm/isa_traits.hh +++ b/src/arch/arm/isa_traits.hh @@ -104,6 +104,8 @@ namespace ArmISA const int WordBytes = 4; const int HalfwordBytes = 2; const int ByteBytes = 1; + + const uint32_t HighVecs = 0xFFFF0000; }; using namespace ArmISA; diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index ba394d49c5..45233a7646 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -55,7 +55,7 @@ namespace ArmISA enum MiscRegIndex { MISCREG_CPSR = 0, - MISCREG_SPSR, + MISCREG_SPSR, MISCREG_SPSR_FIQ, MISCREG_SPSR_IRQ, MISCREG_SPSR_SVC, @@ -66,13 +66,13 @@ namespace ArmISA MISCREG_FPSID, MISCREG_FPSCR, MISCREG_FPEXC, - NUM_MISCREGS + MISCREG_SCTLR, + NUM_MISCREGS }; const char * const miscRegName[NUM_MISCREGS] = { - "cpsr", - "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und", "spsr_abt", - "fpsr" + "cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und", + "spsr_abt", "fpsr", "fpsid", "fpscr", "fpexc", "sctlr" }; BitUnion32(CPSR) @@ -81,8 +81,10 @@ namespace ArmISA Bitfield<29> c; Bitfield<28> v; Bitfield<27> q; + Bitfield<26,25> it1; Bitfield<24> j; Bitfield<19, 16> ge; + Bitfield<15,10> it2; Bitfield<9> e; Bitfield<8> a; Bitfield<7> i; @@ -90,6 +92,31 @@ namespace ArmISA Bitfield<5> t; Bitfield<4, 0> mode; EndBitUnion(CPSR) + + BitUnion32(SCTLR) + Bitfield<30> te; // Thumb Exception Enable + Bitfield<29> afe; // Access flag enable + Bitfield<28> tre; // TEX Remap bit + Bitfield<27> nmfi;// Non-maskable fast interrupts enable + Bitfield<25> ee; // Exception Endianness bit + Bitfield<24> ve; // Interrupt vectors enable + Bitfield<23> rao1;// Read as one + Bitfield<22> u; // Alignment (now unused) + Bitfield<21> fi; // Fast interrupts configuration enable + Bitfield<18> rao2;// Read as one + Bitfield<17> ha; // Hardware access flag enable + Bitfield<16> rao3;// Read as one + Bitfield<14> rr; // Round robin cache replacement + Bitfield<13> v; // Base address for exception vectors + Bitfield<12> i; // instruction cache enable + Bitfield<11> z; // branch prediction enable bit + Bitfield<10> sw; // Enable swp/swpb + Bitfield<6,3> rao4;// Read as one + Bitfield<7> b; // Endianness support (unused) + Bitfield<2> c; // Cache enable bit + Bitfield<1> a; // Alignment fault checking + Bitfield<0> m; // MMU enable bit + EndBitUnion(SCTLR) }; #endif // __ARCH_ARM_MISCREGS_HH__ diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc new file mode 100644 index 0000000000..8cfa48e18c --- /dev/null +++ b/src/arch/arm/utility.cc @@ -0,0 +1,19 @@ + +#include +#include + + +namespace ArmISA { + +void +initCPU(ThreadContext *tc, int cpuId) +{ + // Reset CP15?? What does that mean -- ali + + // FPEXC.EN = 0 + + static Fault reset = new Reset(); + if (cpuId == 0) + reset->invoke(tc); +} + From b8120f6c38f212acbfd246a3081842a9e3d06eb3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 21:10:18 -0800 Subject: [PATCH 102/160] Mem: Eliminate the NO_FAULT request flag. --- src/arch/alpha/faults.cc | 2 +- src/arch/alpha/isa/decoder.isa | 2 +- src/arch/alpha/isa/mem.isa | 2 +- src/arch/mips/isa/formats/mem.isa | 2 +- src/cpu/checker/cpu.cc | 2 +- src/cpu/simple/atomic.cc | 16 +++++++++++++--- src/cpu/simple/timing.cc | 8 ++++++++ src/mem/request.hh | 2 -- 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index e93e167112..ff6de8d03c 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -144,7 +144,7 @@ DtbFault::invoke(ThreadContext *tc) // read, like the EV5). The EV6 approach is cleaner and seems to // work with EV5 PAL code, but not the other way around. if (!tc->misspeculating() && - reqFlags.noneSet(Request::VPTE|Request::NO_FAULT)) { + reqFlags.noneSet(Request::VPTE | Request::PREFETCH)) { // set VA register with faulting address tc->setMiscRegNoEffect(IPR_VA, vaddr); diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index cb43fcb74f..52e124ad5a 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -627,7 +627,7 @@ decode OPCODE default Unknown::unknown() { format MiscPrefetch { 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, {{ xc->writeHint(EA, 64, memAccessFlags); }}, - mem_flags = NO_FAULT, + mem_flags = PREFETCH, inst_flags = [IsMemRef, IsDataPrefetch, IsStore, MemWriteOp]); } diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa index fedfbf55d9..b1703221f5 100644 --- a/src/arch/alpha/isa/mem.isa +++ b/src/arch/alpha/isa/mem.isa @@ -548,7 +548,7 @@ def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, pf_flags = makeList(pf_flags) inst_flags = makeList(inst_flags) - pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_mem_flags = mem_flags + pf_flags + ['PREFETCH'] pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp'] diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa index adcb161374..161a52b069 100644 --- a/src/arch/mips/isa/formats/mem.isa +++ b/src/arch/mips/isa/formats/mem.isa @@ -619,7 +619,7 @@ def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; def format Prefetch(ea_code = {{ EA = Rs + disp; }}, mem_flags = [], pf_flags = [], inst_flags = []) {{ - pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_mem_flags = mem_flags + pf_flags + ['PREFETCH'] pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp'] diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc index 7dacc58ffe..16b779e06b 100644 --- a/src/cpu/checker/cpu.cc +++ b/src/cpu/checker/cpu.cc @@ -326,7 +326,7 @@ CheckerCPU::checkFlags(Request *req) { // Remove any dynamic flags that don't have to do with the request itself. unsigned flags = unverifiedReq->getFlags(); - unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | NO_FAULT; + unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | PREFETCH; flags = flags & (mask); if (flags == req->getFlags()) { return false; diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index cd4f5457eb..c092b5b1fd 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -353,8 +353,14 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) recordEvent("Uncached Read"); //If there's a fault, return it - if (fault != NoFault) - return fault; + if (fault != NoFault) { + if (req->isPrefetch()) { + return NoFault; + } else { + return fault; + } + } + //If we don't need to access a second cache line, stop now. if (secondAddr <= addr) { @@ -531,7 +537,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) assert(locked); locked = false; } - return fault; + if (fault != NoFault && req->isPrefetch()) { + return NoFault; + } else { + return fault; + } } /* diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 8d3bae3f69..6b22d2fcf3 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -273,6 +273,8 @@ TimingSimpleCPU::sendData(Fault fault, RequestPtr req, { _status = Running; if (fault != NoFault) { + if (req->isPrefetch()) + fault = NoFault; delete data; delete req; @@ -315,6 +317,10 @@ TimingSimpleCPU::sendSplitData(Fault fault1, Fault fault2, { _status = Running; if (fault1 != NoFault || fault2 != NoFault) { + if (req1->isPrefetch()) + fault1 = NoFault; + if (req2->isPrefetch()) + fault2 = NoFault; delete data; delete req1; delete req2; @@ -360,6 +366,8 @@ TimingSimpleCPU::sendSplitData(Fault fault1, Fault fault2, void TimingSimpleCPU::translationFault(Fault fault) { + // fault may be NoFault in cases where a fault is suppressed, + // for instance prefetches. numCycles += tickToCycles(curTick - previousTick); previousTick = curTick; diff --git a/src/mem/request.hh b/src/mem/request.hh index c8c31ffcda..f2cc4647c0 100644 --- a/src/mem/request.hh +++ b/src/mem/request.hh @@ -72,8 +72,6 @@ class Request : public FastAlloc /** This request is to a memory mapped register. */ static const FlagsType MMAPED_IPR = 0x00002000; - /** The request should not cause a page fault. */ - static const FlagsType NO_FAULT = 0x00010000; /** The request should ignore unaligned access faults */ static const FlagsType NO_ALIGN_FAULT = 0x00020000; /** The request should ignore unaligned access faults */ From 5524af83efab8ee502f84987d56306ecd140ab80 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 23:44:05 -0800 Subject: [PATCH 103/160] ARM: Fix some bugs in the ISA desc and fill out some instructions. --- src/arch/arm/isa/bitfields.isa | 1 + src/arch/arm/isa/decoder.isa | 64 +++++++++++++++++++-------- src/arch/arm/isa/formats/pred.isa | 72 +++++++++++++++++++++---------- src/arch/arm/isa/operands.isa | 1 + src/arch/arm/types.hh | 1 + 5 files changed, 98 insertions(+), 41 deletions(-) diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index 5785939cc5..fc75ecf792 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -43,6 +43,7 @@ def bitfield OPCODE_23_20 opcode23_20; def bitfield OPCODE_23_21 opcode23_21; def bitfield OPCODE_22 opcode22; def bitfield OPCODE_19 opcode19; +def bitfield OPCODE_18 opcode18; def bitfield OPCODE_15_12 opcode15_12; def bitfield OPCODE_15 opcode15; def bitfield MISC_OPCODE miscOpcode; diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index ebadeb9852..b4b820b06a 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -51,20 +51,25 @@ format DataOp { resTemp = ((uint64_t)Rm)*((uint64_t)Rs); Rd = (uint32_t)(resTemp & 0xffffffff); Rn = (uint32_t)(resTemp >> 32); - }}); - 0x5: WarnUnimpl::smlal(); + }}, llbit); + 0x5: smlal({{ + resTemp = ((int64_t)Rm) * ((int64_t)Rs); + resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd); + Rd = (uint32_t)(resTemp & 0xffffffff); + Rn = (uint32_t)(resTemp >> 32); + }}, llbit); 0x6: smull({{ resTemp = ((int64_t)(int32_t)Rm)* ((int64_t)(int32_t)Rs); Rd = (int32_t)(resTemp & 0xffffffff); Rn = (int32_t)(resTemp >> 32); - }}); + }}, llbit); 0x7: umlal({{ resTemp = ((uint64_t)Rm)*((uint64_t)Rs); resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd); Rd = (uint32_t)(resTemp & 0xffffffff); Rn = (uint32_t)(resTemp >> 32); - }}); + }}, llbit); } 1: decode PUBWL { 0x10: WarnUnimpl::swp(); @@ -105,9 +110,17 @@ format DataOp { } 1: decode MISC_OPCODE { 0x0: decode OPCODE { - 0x8: WarnUnimpl::mrs_cpsr(); - 0x9: WarnUnimpl::msr_cpsr(); - 0xa: WarnUnimpl::mrs_spsr(); + 0x8: PredOp::mrs_cpsr({{ Rd = Cpsr | CondCodes; }}); + 0x9: PredOp::msr_cpsr({{ + //assert(!RN<1:0>); + if (OPCODE_18) { + Cpsr = Cpsr<31:20> | mbits(Rm, 19, 16) | Cpsr<15:0>; + } + if (OPCODE_19) { + CondCodes = mbits(Rm, 31,27); + } + }}); + 0xa: PredOp::mrs_spsr({{ Rd = 0; // should be SPSR}}); 0xb: WarnUnimpl::msr_spsr(); } 0x1: decode OPCODE { @@ -129,28 +142,32 @@ format DataOp { 0xb: WarnUnimpl::qdsub(); } 0x8: decode OPCODE { - 0x8: WarnUnimpl::smlabb(); + 0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); 0x9: WarnUnimpl::smlalbb(); 0xa: WarnUnimpl::smlawb(); - 0xb: WarnUnimpl::smulbb(); + 0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none); } 0xa: decode OPCODE { - 0x8: WarnUnimpl::smlatb(); - 0x9: WarnUnimpl::smulwb(); + 0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); + 0x9: smulwb({{ + Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16); + }}, none); 0xa: WarnUnimpl::smlaltb(); - 0xb: WarnUnimpl::smultb(); + 0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none); } 0xc: decode OPCODE { - 0x8: WarnUnimpl::smlabt(); + 0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); 0x9: WarnUnimpl::smlawt(); 0xa: WarnUnimpl::smlalbt(); - 0xb: WarnUnimpl::smulbt(); + 0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none); } 0xe: decode OPCODE { - 0x8: WarnUnimpl::smlatt(); - 0x9: WarnUnimpl::smulwt(); + 0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); + 0x9: smulwt({{ + Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16); + }}, none); 0xa: WarnUnimpl::smlaltt(); - 0xb: WarnUnimpl::smultt(); + 0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none); } } } @@ -184,8 +201,16 @@ format DataOp { } 1: decode OPCODE { // The following two instructions aren't supposed to be defined - 0x8: WarnUnimpl::undefined_instruction(); - 0x9: WarnUnimpl::undefined_instruction(); + 0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }}); + 0x9: DataImmOp::msr_ia_cpsr ({{ + //assert(!RN<1:0>); + if (OPCODE_18) { + Cpsr = Cpsr<31:20> | rotated_imm | Cpsr<15:0>; + } + if (OPCODE_19) { + CondCodes = rotated_imm; + } + }}); 0xa: WarnUnimpl::mrs_i_cpsr(); 0xb: WarnUnimpl::mrs_i_spsr(); @@ -440,6 +465,7 @@ format DataOp { } } } + 0xf: WarnUnimpl::mcr_cp15(); } format PredOp { // ARM System Call (SoftWare Interrupt) diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa index 3c97560fde..0d6ee32f7d 100644 --- a/src/arch/arm/isa/formats/pred.isa +++ b/src/arch/arm/isa/formats/pred.isa @@ -81,32 +81,45 @@ def template DataImmDecode {{ }}; let {{ + + calcCcCode = ''' + if (%(canOverflow)s){ + cprintf("canOverflow: %%d\\n", Rd < resTemp); + replaceBits(CondCodes, 27, Rd < resTemp); + } else { + uint16_t _ic, _iv, _iz, _in; + _in = (resTemp >> %(negBit)d) & 1; + _iz = (resTemp == 0); + _iv = %(ivValue)s & 1; + _ic = %(icValue)s & 1; + + CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | + (CondCodes & 0x0FFFFFFF); - calcCcCode = ''' - uint16_t _ic, _iv, _iz, _in; - - _in = (resTemp >> 31) & 1; - _iz = (resTemp == 0); - _iv = %(ivValue)s & 1; - _ic = %(icValue)s & 1; - - CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | - (CondCodes & 0x0FFFFFFF); - - DPRINTF(Arm, "in = %%d\\n", _in); - DPRINTF(Arm, "iz = %%d\\n", _iz); - DPRINTF(Arm, "ic = %%d\\n", _ic); - DPRINTF(Arm, "iv = %%d\\n", _iv); + DPRINTF(Arm, "in = %%d\\n", _in); + DPRINTF(Arm, "iz = %%d\\n", _iz); + DPRINTF(Arm, "ic = %%d\\n", _ic); + DPRINTF(Arm, "iv = %%d\\n", _iv); + } ''' - }}; let {{ def getCcCode(flagtype): icReg = icImm = iv = '' + negBit = 31 + canOverflow = 'false' + if flagtype == "none": icReg = icImm = 'CondCodes<29:>' iv = 'CondCodes<28:>' + elif flagtype == "llbit": + icReg = icImm = 'CondCodes<29:>' + iv = 'CondCodes<28:>' + negBit = 63 + elif flagtype == "overflow": + canOverflow = "true" + icReg = icImm = iv = '0' elif flagtype == "add": icReg = icImm = 'findCarry(32, resTemp, Rn, op2)' iv = 'findOverflow(32, resTemp, Rn, op2)' @@ -117,17 +130,32 @@ let {{ icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)' iv = 'findOverflow(32, resTemp, op2, ~Rn)' else: - icReg = 'shift_carry_rs(Rm, Rs, shift, CondCodes<29:>)' + icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)' icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)' iv = 'CondCodes<28:>' - return (calcCcCode % {"icValue" : icReg, "ivValue" : iv}, - calcCcCode % {"icValue" : icImm, "ivValue" : iv}) + return (calcCcCode % {"icValue" : icReg, + "ivValue" : iv, + "negBit" : negBit, + "canOverflow" : canOverflow }, + calcCcCode % {"icValue" : icImm, + "ivValue" : iv, + "negBit" : negBit, + "canOverflow" : canOverflow }) def getImmCcCode(flagtype): ivValue = icValue = '' + negBit = 31 + canOverflow = 'false' if flagtype == "none": icValue = 'CondCodes<29:>' ivValue = 'CondCodes<28:>' + elif flagtype == "llbit": + icValue = 'CondCodes<29:>' + ivValue = 'CondCodes<28:>' + negBit = 63 + elif flagtype == "overflow": + icVaule = ivValue = '0' + canOverflow = "true" elif flagtype == "add": icValue = 'findCarry(32, resTemp, Rn, rotated_imm)' ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)' @@ -145,11 +173,11 @@ let {{ def format DataOp(code, flagtype = logic) {{ (regCcCode, immCcCode) = getCcCode(flagtype) - regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs, - shift, CondCodes<29:0>); + regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>, + shift, CondCodes<29:>); op2 = op2;''' + code immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size, - shift, CondCodes<29:0>); + shift, CondCodes<29:>); op2 = op2;''' + code regIop = InstObjParams(name, Name, 'PredIntOp', {"code": regCode, diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 02acc8ed70..5ae0b8912d 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -58,6 +58,7 @@ def operands {{ 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite), 'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite), 'R7': ('IntReg', 'uw', '7', 'IsInteger', 5), + 'R0': ('IntReg', 'uw', '0', 'IsInteger', 0), #Destination register for load/store double instructions 'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite), diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index d5cc07eaf6..237bf8412b 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -52,6 +52,7 @@ namespace ArmISA Bitfield<23, 21> opcode23_21; Bitfield<22> opcode22; Bitfield<19> opcode19; + Bitfield<18> opcode18; Bitfield<15, 12> opcode15_12; Bitfield<15> opcode15; Bitfield<7, 4> miscOpcode; From 8f6744c19c7d6cf87a207e901503c3435c1ff7a9 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 11 Nov 2009 17:49:09 -0500 Subject: [PATCH 104/160] X86: add ULL to 1's being shifted in 64-bit values Some of the micro-ops weren't casting 1 to ULL before shifting, which can cause problems. On the perl makerand input this caused some values to be negative that shouldn't have been. The casts are done as ULL(1) instead of 1ULL to match others in the m5 code base. --- src/arch/x86/isa/microops/mediaop.isa | 31 ++++++++++++++------------- src/arch/x86/isa/microops/regop.isa | 4 ++-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa index fa32583b08..4052f254d7 100644 --- a/src/arch/x86/isa/microops/mediaop.isa +++ b/src/arch/x86/isa/microops/mediaop.isa @@ -452,7 +452,7 @@ let {{ if (signBit) { if (overflow != mask(destBits - srcBits + 1)) { if (ext & 0x1) - picked = (1 << (destBits - 1)); + picked = (ULL(1) << (destBits - 1)); else picked = 0; } @@ -480,7 +480,7 @@ let {{ if (signBit) { if (overflow != mask(destBits - srcBits + 1)) { if (ext & 0x1) - picked = (1 << (destBits - 1)); + picked = (ULL(1) << (destBits - 1)); else picked = 0; } @@ -642,10 +642,10 @@ let {{ int loIndex = (i + 0) * sizeBits; uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (sizeBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (sizeBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); uint64_t resBits; if (ext & 0x2) { @@ -680,10 +680,10 @@ let {{ int loIndex = (i + 0) * sizeBits; uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (sizeBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (sizeBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); uint64_t resBits; if (ext & 0x2) { @@ -957,7 +957,7 @@ let {{ int resSign = bits(resBits, sizeBits - 1); if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { if (resSign == 0) - resBits = (1 << (sizeBits - 1)); + resBits = (ULL(1) << (sizeBits - 1)); else resBits = mask(sizeBits - 1); } @@ -996,7 +996,7 @@ let {{ int resSign = bits(resBits, sizeBits - 1); if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { if (resSign == 0) - resBits = (1 << (sizeBits - 1)); + resBits = (ULL(1) << (sizeBits - 1)); else resBits = mask(sizeBits - 1); } @@ -1032,16 +1032,16 @@ let {{ if (ext & 0x2) { int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (srcBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (srcBits - 1)))); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (srcBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (srcBits - 1)))); resBits = (uint64_t)(arg1 * arg2); } else { resBits = arg1Bits * arg2Bits; } if (ext & 0x4) - resBits += (1 << (destBits - 1)); + resBits += (ULL(1) << (destBits - 1)); if (ext & 0x8) resBits >>= destBits; @@ -1142,7 +1142,7 @@ let {{ } else { resBits = (arg1Bits >> shiftAmt); resBits = resBits | - (0 - (resBits & (1 << (sizeBits - 1 - shiftAmt)))); + (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt)))); } result = insertBits(result, hiIndex, loIndex, resBits); @@ -1289,7 +1289,8 @@ let {{ int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1; int srcLoIndex = srcStart + (i + 0) * srcSizeBits; uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex); - int64_t sArg = argBits | (0 - (argBits & (1 << srcHiIndex))); + + int64_t sArg = argBits | (0 - (argBits & (ULL(1) << srcHiIndex))); double arg = sArg; if (destSize == 4) { @@ -1400,10 +1401,10 @@ let {{ int loIndex = (i + 0) * sizeBits; uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (sizeBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (sizeBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); uint64_t resBits = 0; if (((ext & 0x2) == 0 && arg1 == arg2) || diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index fd1ad69259..0b1f9a96a6 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -525,7 +525,7 @@ let {{ code = ''' ProdLow = psrc1 * op2; int halfSize = (dataSize * 8) / 2; - uint64_t shifter = (1ULL << halfSize); + uint64_t shifter = (ULL(1) << halfSize); uint64_t hiResult; uint64_t psrc1_h = psrc1 / shifter; uint64_t psrc1_l = psrc1 & mask(halfSize); @@ -553,7 +553,7 @@ let {{ code = ''' ProdLow = psrc1 * op2; int halfSize = (dataSize * 8) / 2; - uint64_t shifter = (1ULL << halfSize); + uint64_t shifter = (ULL(1) << halfSize); uint64_t psrc1_h = psrc1 / shifter; uint64_t psrc1_l = psrc1 & mask(halfSize); uint64_t psrc2_h = (op2 / shifter) & mask(halfSize); From 48bc573f5f9709480da458e3c4627f7b7afd38f4 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 14 Nov 2009 11:25:00 -0600 Subject: [PATCH 105/160] ARM: Move around decoder to properly decode CP15 --- src/arch/arm/isa/bitfields.isa | 1 + src/arch/arm/isa/decoder.isa | 206 +++++++++++++++++---------------- src/arch/arm/types.hh | 1 + 3 files changed, 109 insertions(+), 99 deletions(-) diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index fc75ecf792..816cd4b6de 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -42,6 +42,7 @@ def bitfield OPCODE_24 opcode24; def bitfield OPCODE_23_20 opcode23_20; def bitfield OPCODE_23_21 opcode23_21; def bitfield OPCODE_22 opcode22; +def bitfield OPCODE_20 opcode20; def bitfield OPCODE_19 opcode19; def bitfield OPCODE_18 opcode18; def bitfield OPCODE_15_12 opcode15_12; diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index b4b820b06a..20b544a7ca 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -355,77 +355,79 @@ format DataOp { } } 0x7: decode OPCODE_24 { - 0: decode CPNUM { - // Coprocessor Instructions - 0x1: decode OPCODE_4 { + 0: decode OPCODE_4 { + 0: decode CPNUM { format FloatOp { - // Basic FPA Instructions - 0: decode OPCODE_23_20 { - 0x0: decode OPCODE_15 { - 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }}); - 1: mvf({{ Fd.sf = Fm.sf; }}); - } - 0x1: decode OPCODE_15 { - 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }}); - 1: mnf({{ Fd.sf = -Fm.sf; }}); - } - 0x2: decode OPCODE_15 { - 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }}); - 1: abs({{ Fd.sf = fabs(Fm.sf); }}); - } - 0x3: decode OPCODE_15 { - 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }}); - 1: rnd({{ Fd.sf = rint(Fm.sf); }}); - } - 0x4: decode OPCODE_15 { - 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }}); - 1: sqt({{ Fd.sf = sqrt(Fm.sf); }}); - } - 0x5: decode OPCODE_15 { - 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }}); - 1: log({{ Fd.sf = log10(Fm.sf); }}); - } - 0x6: decode OPCODE_15 { - 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }}); - 1: lgn({{ Fd.sf = log(Fm.sf); }}); - } - 0x7: decode OPCODE_15 { - 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }}); - 1: exp({{ Fd.sf = exp(Fm.sf); }}); - } - 0x8: decode OPCODE_15 { - 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }}); - 1: sin({{ Fd.sf = sin(Fm.sf); }}); - } - 0x9: decode OPCODE_15 { - 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }}); - 1: cos({{ Fd.sf = cos(Fm.sf); }}); - } - 0xa: decode OPCODE_15 { - 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }}); - 1: tan({{ Fd.sf = tan(Fm.sf); }}); - } - 0xb: decode OPCODE_15 { - 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }}); - 1: asn({{ Fd.sf = asin(Fm.sf); }}); - } - 0xc: decode OPCODE_15 { - 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }}); - 1: acs({{ Fd.sf = acos(Fm.sf); }}); - } - 0xd: decode OPCODE_15 { - 1: atn({{ Fd.sf = atan(Fm.sf); }}); - } - 0xe: decode OPCODE_15 { - // Unnormalised Round - 1: FailUnimpl::urd(); - } - 0xf: decode OPCODE_15 { - // Normalise - 1: FailUnimpl::nrm(); - } - } - 1: decode OPCODE_15_12 { + 0x1: decode OPCODE_23_20 { + 0x0: decode OPCODE_15 { + 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }}); + 1: mvf({{ Fd.sf = Fm.sf; }}); + } + 0x1: decode OPCODE_15 { + 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }}); + 1: mnf({{ Fd.sf = -Fm.sf; }}); + } + 0x2: decode OPCODE_15 { + 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }}); + 1: abs({{ Fd.sf = fabs(Fm.sf); }}); + } + 0x3: decode OPCODE_15 { + 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }}); + 1: rnd({{ Fd.sf = rint(Fm.sf); }}); + } + 0x4: decode OPCODE_15 { + 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }}); + 1: sqt({{ Fd.sf = sqrt(Fm.sf); }}); + } + 0x5: decode OPCODE_15 { + 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }}); + 1: log({{ Fd.sf = log10(Fm.sf); }}); + } + 0x6: decode OPCODE_15 { + 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }}); + 1: lgn({{ Fd.sf = log(Fm.sf); }}); + } + 0x7: decode OPCODE_15 { + 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }}); + 1: exp({{ Fd.sf = exp(Fm.sf); }}); + } + 0x8: decode OPCODE_15 { + 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }}); + 1: sin({{ Fd.sf = sin(Fm.sf); }}); + } + 0x9: decode OPCODE_15 { + 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }}); + 1: cos({{ Fd.sf = cos(Fm.sf); }}); + } + 0xa: decode OPCODE_15 { + 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }}); + 1: tan({{ Fd.sf = tan(Fm.sf); }}); + } + 0xb: decode OPCODE_15 { + 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }}); + 1: asn({{ Fd.sf = asin(Fm.sf); }}); + } + 0xc: decode OPCODE_15 { + 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }}); + 1: acs({{ Fd.sf = acos(Fm.sf); }}); + } + 0xd: decode OPCODE_15 { + 1: atn({{ Fd.sf = atan(Fm.sf); }}); + } + 0xe: decode OPCODE_15 { + // Unnormalised Round + 1: FailUnimpl::urd(); + } + 0xf: decode OPCODE_15 { + // Normalise + 1: FailUnimpl::nrm(); + } + } // OPCODE_23_20 + } // format FloatOp + } // CPNUM + 1: decode CPNUM { // 27-24=1110,4 ==1 + 1: decode OPCODE_15_12 { + format FloatOp { 0xf: decode OPCODE_23_21 { format FloatCmp { 0x4: cmf({{ Fn.df }}, {{ Fm.df }}); @@ -448,37 +450,43 @@ format DataOp { 0x4: FailUnimpl::wfc(); 0x5: FailUnimpl::rfc(); } - } + } // format FloatOp } + 0xa: decode MISC_OPCODE { + 0x1: decode MEDIA_OPCODE { + 0xf: decode RN { + 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }}); + 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }}); + 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }}); + } + 0xe: decode RN { + 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }}); + 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }}); + 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }}); + } + } // MEDIA_OPCODE (MISC_OPCODE 0x1) + } // MISC_OPCODE (CPNUM 0xA) + 0xf: decode OPCODE_20 { + 0: WarnUnimpl::mcr_cp15(); + 1: WarnUnimpl::mrc_cp15(); + } + } // CPNUM (OP4 == 1) + } //OPCODE_4 + +#if FULL_SYSTEM + 1: PredOp::swi({{ fault = new SupervisorCall; }}, IsSerializeAfter, IsNonSpeculative, IsSyscall); +#else + 1: PredOp::swi({{ if (testPredicate(CondCodes, condCode)) + { + if (IMMED_23_0) + xc->syscall(IMMED_23_0); + else + xc->syscall(R7); } - 0xa: decode MISC_OPCODE { - 0x1: decode MEDIA_OPCODE { - 0xf: decode RN { - 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }}); - 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }}); - 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }}); - } - 0xe: decode RN { - 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }}); - 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }}); - 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }}); - } - } - } - 0xf: WarnUnimpl::mcr_cp15(); - } - format PredOp { - // ARM System Call (SoftWare Interrupt) - 1: swi({{ if (testPredicate(CondCodes, condCode)) - { - if (IMMED_23_0) - xc->syscall(IMMED_23_0); - else - xc->syscall(R7); - } - }}); - } - } + }}); +#endif // FULL_SYSTEM + } // OPCODE_24 + } } diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 237bf8412b..e37fd3a1f5 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -50,6 +50,7 @@ namespace ArmISA Bitfield<24> opcode24; Bitfield<23, 20> opcode23_20; Bitfield<23, 21> opcode23_21; + Bitfield<20> opcode20; Bitfield<22> opcode22; Bitfield<19> opcode19; Bitfield<18> opcode18; From 4e9ce1805e3bbc6a6085502e94e0298eada77113 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 14 Nov 2009 11:49:01 -0600 Subject: [PATCH 106/160] SE: Fix SE mode OS X compilation. --- src/kern/linux/linux.hh | 2 +- src/sim/syscall_emul.cc | 12 ++++++++++-- src/sim/syscall_emul.hh | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 736213762b..7fe107139b 100644 --- a/src/kern/linux/linux.hh +++ b/src/kern/linux/linux.hh @@ -138,7 +138,7 @@ class Linux : public OperatingSystem }; /// Clock ticks per second, for times(). - static const int _SC_CLK_TCK = 100; + static const int M5_SC_CLK_TCK = 100; /// For times(). struct tms { diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 4461e8b528..4726decc57 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -461,12 +461,16 @@ truncate64Func(SyscallDesc *desc, int num, if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, index))) return -EFAULT; - loff_t length = process->getSyscallArg(tc, index, 64); + int64_t length = process->getSyscallArg(tc, index, 64); // Adjust path for current working directory path = process->fullPath(path); +#if NO_STAT64 + int result = truncate(path.c_str(), length); +#else int result = truncate64(path.c_str(), length); +#endif return (result == -1) ? -errno : result; } @@ -480,9 +484,13 @@ ftruncate64Func(SyscallDesc *desc, int num, if (fd < 0) return -EBADF; - loff_t length = process->getSyscallArg(tc, index, 64); + int64_t length = process->getSyscallArg(tc, index, 64); +#if NO_STAT64 + int result = ftruncate(fd, length); +#else int result = ftruncate64(fd, length); +#endif return (result == -1) ? -errno : result; } diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 27c26afb0f..66e8001836 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -1187,7 +1187,7 @@ timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process, TypedBufferArg bufp(process->getSyscallArg(tc, index)); // Fill in the time structure (in clocks) - int64_t clocks = curTick * OS::_SC_CLK_TCK / Clock::Int::s; + int64_t clocks = curTick * OS::M5_SC_CLK_TCK / Clock::Int::s; bufp->tms_utime = clocks; bufp->tms_stime = 0; bufp->tms_cutime = 0; From 50b9149c7572b4cff351f2c28726226030cefdbd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:29 -0800 Subject: [PATCH 107/160] ARM: Hook up the moded versions of the SPSR. These registers can be accessed directly, or through MISCREG_SPSR which will act as whichever SPSR is appropriate for the current mode. --- src/arch/arm/isa.hh | 56 ++++++++++++++++++++++++++++++++--- src/arch/arm/isa/operands.isa | 13 ++++---- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index a270f046bf..905eb01836 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -100,20 +100,69 @@ namespace ArmISA readMiscRegNoEffect(int misc_reg) { assert(misc_reg < NumMiscRegs); + if (misc_reg == MISCREG_SPSR) { + CPSR cpsr = miscRegs[MISCREG_CPSR]; + switch (cpsr.mode) { + case MODE_USER: + return miscRegs[MISCREG_SPSR]; + case MODE_FIQ: + return miscRegs[MISCREG_SPSR_FIQ]; + case MODE_IRQ: + return miscRegs[MISCREG_SPSR_IRQ]; + case MODE_SVC: + return miscRegs[MISCREG_SPSR_SVC]; + case MODE_MON: + return miscRegs[MISCREG_SPSR_MON]; + case MODE_ABORT: + return miscRegs[MISCREG_SPSR_ABT]; + case MODE_UNDEFINED: + return miscRegs[MISCREG_SPSR_UND]; + default: + return miscRegs[MISCREG_SPSR]; + } + } return miscRegs[misc_reg]; } MiscReg readMiscReg(int misc_reg, ThreadContext *tc) { - assert(misc_reg < NumMiscRegs); - return miscRegs[misc_reg]; + return readMiscRegNoEffect(misc_reg); } void setMiscRegNoEffect(int misc_reg, const MiscReg &val) { assert(misc_reg < NumMiscRegs); + if (misc_reg == MISCREG_SPSR) { + CPSR cpsr = miscRegs[MISCREG_CPSR]; + switch (cpsr.mode) { + case MODE_USER: + miscRegs[MISCREG_SPSR] = val; + return; + case MODE_FIQ: + miscRegs[MISCREG_SPSR_FIQ] = val; + return; + case MODE_IRQ: + miscRegs[MISCREG_SPSR_IRQ] = val; + return; + case MODE_SVC: + miscRegs[MISCREG_SPSR_SVC] = val; + return; + case MODE_MON: + miscRegs[MISCREG_SPSR_MON] = val; + return; + case MODE_ABORT: + miscRegs[MISCREG_SPSR_ABT] = val; + return; + case MODE_UNDEFINED: + miscRegs[MISCREG_SPSR_UND] = val; + return; + default: + miscRegs[MISCREG_SPSR] = val; + return; + } + } miscRegs[misc_reg] = val; } @@ -123,8 +172,7 @@ namespace ArmISA if (misc_reg == MISCREG_CPSR) { updateRegMap(val); } - assert(misc_reg < NumMiscRegs); - miscRegs[misc_reg] = val; + return setMiscRegNoEffect(misc_reg, val); } int diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 5ae0b8912d..fe085cdac3 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -82,11 +82,12 @@ def operands {{ 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30), 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40), - 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41), - 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42), - 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43), - 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44), - 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45), - 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46) + 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', 'IsInteger', 41), + 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 42), + 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 43), + 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 44), + 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 45), + 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50), + 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51) }}; From 1df0025e28d8f9699f86fc118db3b93a0f1ec50c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:29 -0800 Subject: [PATCH 108/160] ARM: More accurately describe the effects of using the control operands. --- src/arch/arm/isa/operands.isa | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index fe085cdac3..aadefc79c2 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -81,12 +81,12 @@ def operands {{ #Memory Operand 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30), - 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40), - 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', 'IsInteger', 41), - 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 42), - 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 43), - 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 44), - 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 45), + 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', (None, None, 'IsControl'), 40), + 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', (None, None, 'IsControl'), 41), + 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', (None, None, 'IsControl'), 42), + 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', (None, None, 'IsControl'), 43), + 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', (None, None, 'IsControl'), 44), + 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', (None, None, 'IsControl'), 45), 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50), 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51) From 812e390693253818c49585daf35692759a1c82d4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:29 -0800 Subject: [PATCH 109/160] ARM: Fix up the implmentation of the mrs instruction. --- src/arch/arm/isa/decoder.isa | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 20b544a7ca..cd13fa4209 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -110,7 +110,9 @@ format DataOp { } 1: decode MISC_OPCODE { 0x0: decode OPCODE { - 0x8: PredOp::mrs_cpsr({{ Rd = Cpsr | CondCodes; }}); + 0x8: PredOp::mrs_cpsr({{ + Rd = (Cpsr | CondCodes) & 0xF8FF03DF; + }}); 0x9: PredOp::msr_cpsr({{ //assert(!RN<1:0>); if (OPCODE_18) { @@ -120,7 +122,7 @@ format DataOp { CondCodes = mbits(Rm, 31,27); } }}); - 0xa: PredOp::mrs_spsr({{ Rd = 0; // should be SPSR}}); + 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); 0xb: WarnUnimpl::msr_spsr(); } 0x1: decode OPCODE { From e543f162475b93a1cae7f301a7edd76067d81ba7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: [PATCH 110/160] ARM: Write some functions to write to the CPSR and SPSR for instructions. --- src/arch/arm/insts/static_inst.hh | 50 +++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index c963c1827d..f2881c3b67 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -74,6 +74,56 @@ class ArmStaticInst : public StaticInst void printDataInst(std::ostream &os, bool withImm) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + static uint32_t + cpsrWriteByInstr(CPSR cpsr, uint32_t val, + uint8_t byteMask, bool affectState) + { + bool privileged = (cpsr.mode != MODE_USER); + + uint32_t bitMask = 0; + + if (bits(byteMask, 3)) { + unsigned lowIdx = affectState ? 24 : 27; + bitMask = bitMask | mask(31, lowIdx); + } + if (bits(byteMask, 2)) { + bitMask = bitMask | mask(19, 16); + } + if (bits(byteMask, 1)) { + unsigned highIdx = affectState ? 15 : 9; + unsigned lowIdx = privileged ? 8 : 9; + bitMask = bitMask | mask(highIdx, lowIdx); + } + if (bits(byteMask, 0)) { + if (privileged) { + bitMask = bitMask | mask(7, 6); + bitMask = bitMask | mask(5); + } + if (affectState) + bitMask = bitMask | (1 << 5); + } + + return ((uint32_t)cpsr & ~bitMask) | (val & bitMask); + } + + static uint32_t + spsrWriteByInstr(uint32_t spsr, uint32_t val, + uint8_t byteMask, bool affectState) + { + uint32_t bitMask = 0; + + if (bits(byteMask, 3)) + bitMask = bitMask | mask(31, 24); + if (bits(byteMask, 2)) + bitMask = bitMask | mask(19, 16); + if (bits(byteMask, 1)) + bitMask = bitMask | mask(15, 8); + if (bits(byteMask, 0)) + bitMask = bitMask | mask(7, 0); + + return ((spsr & ~bitMask) | (val & bitMask)); + } }; } From 425ebf6bd736d6a7172476a81e935c7b83467dc9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: [PATCH 111/160] ARM: Add a bitfield to indicate if an immediate should be used. --- src/arch/arm/isa/bitfields.isa | 1 + src/arch/arm/types.hh | 1 + 2 files changed, 2 insertions(+) diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index 816cd4b6de..bd4cfc3203 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -38,6 +38,7 @@ def bitfield ENCODING encoding; def bitfield OPCODE opcode; def bitfield MEDIA_OPCODE mediaOpcode; def bitfield MEDIA_OPCODE2 mediaOpcode2; +def bitfield USEIMM useImm; def bitfield OPCODE_24 opcode24; def bitfield OPCODE_23_20 opcode23_20; def bitfield OPCODE_23_21 opcode23_21; diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index e37fd3a1f5..07fa33ea17 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -45,6 +45,7 @@ namespace ArmISA // All the different types of opcode fields. Bitfield<27, 25> encoding; + Bitfield<25> useImm; Bitfield<24, 21> opcode; Bitfield<24, 20> mediaOpcode; Bitfield<24> opcode24; From e2ab64543b2a206c95fbf38565a50f0d5bba0f2a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: [PATCH 112/160] ARM: Define a mask to differentiate purely CPSR bits from CondCodes bits. --- src/arch/arm/miscregs.hh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 45233a7646..d100efb8ee 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -93,6 +93,10 @@ namespace ArmISA Bitfield<4, 0> mode; EndBitUnion(CPSR) + // This mask selects bits of the CPSR that actually go in the CondCodes + // integer register to allow renaming. + static const uint32_t CondCodesMask = 0xF80F0000; + BitUnion32(SCTLR) Bitfield<30> te; // Thumb Exception Enable Bitfield<29> afe; // Access flag enable From c4042985d7b13ddd6afdd3748e9c619863f1233a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: [PATCH 113/160] ARM: Fix up the implmentation of the msr instruction. --- src/arch/arm/isa/decoder.isa | 37 ++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index cd13fa4209..5e82feb1ba 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -113,17 +113,34 @@ format DataOp { 0x8: PredOp::mrs_cpsr({{ Rd = (Cpsr | CondCodes) & 0xF8FF03DF; }}); - 0x9: PredOp::msr_cpsr({{ - //assert(!RN<1:0>); - if (OPCODE_18) { - Cpsr = Cpsr<31:20> | mbits(Rm, 19, 16) | Cpsr<15:0>; - } - if (OPCODE_19) { - CondCodes = mbits(Rm, 31,27); - } - }}); + 0x9: decode USEIMM { + // The mask field is the same as the RN index. + 0: PredImmOp::msr_cpsr_imm({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + rotated_imm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + 1: PredOp::msr_cpsr_reg({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + Rm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + } 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); - 0xb: WarnUnimpl::msr_spsr(); + 0xb: decode USEIMM { + // The mask field is the same as the RN index. + 0: PredImmOp::msr_spsr_imm({{ + Spsr = spsrWriteByInstr(Spsr, rotated_imm, + RN, false); + }}); + 1: PredOp::msr_spsr_reg({{ + Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); + }}); + } } 0x1: decode OPCODE { 0x9: BranchExchange::bx({{ }}); From 5ca47da599dfa6c2ba4386fdcce7b43095d807e9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 20:57:59 -0800 Subject: [PATCH 114/160] ARM: Switch the immediate and register versions of msr. These were accidently transposed. This change straightens them out. From b41725f7234e17d6d66d697ef415a4cb1bae80d9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 21:03:10 -0800 Subject: [PATCH 115/160] ARM: Check in the actual change from the last commit. The last commit was somehow empty. This was what was supposed to go in it. --- src/arch/arm/isa/decoder.isa | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 5e82feb1ba..27af81382f 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -115,31 +115,31 @@ format DataOp { }}); 0x9: decode USEIMM { // The mask field is the same as the RN index. - 0: PredImmOp::msr_cpsr_imm({{ - uint32_t newCpsr = - cpsrWriteByInstr(Cpsr | CondCodes, - rotated_imm, RN, false); - Cpsr = ~CondCodesMask & newCpsr; - CondCodes = CondCodesMask & newCpsr; - }}); - 1: PredOp::msr_cpsr_reg({{ + 0: PredOp::msr_cpsr_reg({{ uint32_t newCpsr = cpsrWriteByInstr(Cpsr | CondCodes, Rm, RN, false); Cpsr = ~CondCodesMask & newCpsr; CondCodes = CondCodesMask & newCpsr; }}); + 1: PredImmOp::msr_cpsr_imm({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + rotated_imm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); } 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); 0xb: decode USEIMM { // The mask field is the same as the RN index. - 0: PredImmOp::msr_spsr_imm({{ + 0: PredOp::msr_spsr_reg({{ + Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); + }}); + 1: PredImmOp::msr_spsr_imm({{ Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false); }}); - 1: PredOp::msr_spsr_reg({{ - Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); - }}); } } 0x1: decode OPCODE { From 903fb8c73df6feec125204fb4e636468f17b5eec Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 15 Nov 2009 00:15:42 -0800 Subject: [PATCH 116/160] ARM: Create a new type of load uop that restores spsr into cpsr. --- src/arch/arm/isa/formats/macromem.isa | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 9a3185af33..ad27b5a563 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -72,6 +72,18 @@ let {{ 'predicate_test': predicateTest}, ['IsMicroop']) + microLdrRetUopCode = ''' + Ra = Mem; + Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true); + ''' + microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', + 'MicroMemOp', + {'memacc_code': microLdrRetUopCode, + 'ea_code': + 'EA = Rb + (UP ? imm : -imm);', + 'predicate_test': predicateTest}, + ['IsMicroop']) + microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 'MicroMemOp', {'memacc_code': 'Mem = Ra;', @@ -80,14 +92,19 @@ let {{ ['IsMicroop']) header_output = MicroMemDeclare.subst(microLdrUopIop) + \ + MicroMemDeclare.subst(microLdrRetUopIop) + \ MicroMemDeclare.subst(microStrUopIop) decoder_output = MicroConstructor.subst(microLdrUopIop) + \ + MicroConstructor.subst(microLdrRetUopIop) + \ MicroConstructor.subst(microStrUopIop) exec_output = LoadExecute.subst(microLdrUopIop) + \ + LoadExecute.subst(microLdrRetUopIop) + \ StoreExecute.subst(microStrUopIop) + \ LoadInitiateAcc.subst(microLdrUopIop) + \ + LoadInitiateAcc.subst(microLdrRetUopIop) + \ StoreInitiateAcc.subst(microStrUopIop) + \ LoadCompleteAcc.subst(microLdrUopIop) + \ + LoadCompleteAcc.subst(microLdrRetUopIop) + \ StoreCompleteAcc.subst(microStrUopIop) }}; From 9127ee5ac8913eacfc62967bd4b275a1845d8a9b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 15 Nov 2009 00:23:14 -0800 Subject: [PATCH 117/160] ARM: Make the exception return form of ldm restore CPSR. --- src/arch/arm/isa/formats/macromem.isa | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index ad27b5a563..068b48199d 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -210,6 +210,7 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0); unsigned reg = 0; + bool forceUser = machInst.puswl.psruser; for (int i = 1; i < ones + 1; i++) { // Find the next register. while (!bits(regs, reg)) @@ -217,13 +218,19 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) replaceBits(regs, reg, 0); unsigned regIdx = reg; - if (machInst.puswl.psruser) { + if (forceUser) { regIdx = intRegForceUser(regIdx); } if (machInst.puswl.loadOp) { - microOps[i] = - new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr); + if (reg == INTREG_PC && forceUser) { + // This must be the exception return form of ldm. + microOps[i] = + new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr); + } else { + microOps[i] = + new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr); + } } else { microOps[i] = new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr); From 171e7f7b24eead1fa82202549e3fad9a0df7b017 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 16 Nov 2009 11:37:03 -0600 Subject: [PATCH 118/160] imported patch isa_fixes2.diff --- src/arch/arm/isa/decoder.isa | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 27af81382f..5a6e8773a8 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -221,18 +221,26 @@ format DataOp { 1: decode OPCODE { // The following two instructions aren't supposed to be defined 0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }}); - 0x9: DataImmOp::msr_ia_cpsr ({{ - //assert(!RN<1:0>); - if (OPCODE_18) { - Cpsr = Cpsr<31:20> | rotated_imm | Cpsr<15:0>; - } - if (OPCODE_19) { - CondCodes = rotated_imm; - } + 0x9: decode RN { + 0: decode IMM { + 0: PredImmOp::nop({{ ; }}); + 1: WarnUnimpl::yield(); + 2: WarnUnimpl::wfe(); + 3: WarnUnimpl::wfi(); + 4: WarnUnimpl::sev(); + } + default: PredImmOp::msr_i_cpsr({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + rotated_imm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + } + 0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }}); + 0xb: PredImmOp::msr_i_spsr({{ + Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false); }}); - - 0xa: WarnUnimpl::mrs_i_cpsr(); - 0xb: WarnUnimpl::mrs_i_spsr(); } } 0x2: AddrMode2::addrMode2(Disp, disp); From 1470dae8e949eaef8232dc621d9074329357265c Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 17 Nov 2009 18:02:08 -0600 Subject: [PATCH 119/160] ARM: Boilerplate full-system code. --HG-- rename : src/arch/sparc/interrupts.hh => src/arch/arm/interrupts.hh rename : src/arch/sparc/kernel_stats.hh => src/arch/arm/kernel_stats.hh rename : src/arch/sparc/stacktrace.cc => src/arch/arm/stacktrace.cc rename : src/arch/sparc/system.cc => src/arch/arm/system.cc rename : src/arch/sparc/system.hh => src/arch/arm/system.hh rename : src/dev/sparc/T1000.py => src/dev/arm/Versatile.py rename : src/dev/sparc/t1000.cc => src/dev/arm/versatile.cc rename : src/dev/sparc/t1000.hh => src/dev/arm/versatile.hh --- build_opts/ARM_FS | 3 + src/arch/arm/ArmInterrupts.py | 33 ++++++++ src/arch/arm/ArmSystem.py | 35 ++++++++ src/arch/arm/SConscript | 11 ++- src/arch/arm/interrupts.cc | 37 +++++++++ src/arch/arm/interrupts.hh | 121 +++++++++++++++++++++++++++ src/arch/arm/kernel_stats.hh | 57 +++++++++++++ src/arch/arm/stacktrace.cc | 151 ++++++++++++++++++++++++++++++++++ src/arch/arm/stacktrace.hh | 17 ++-- src/arch/arm/system.cc | 51 ++++++++++++ src/arch/arm/system.hh | 56 +++++++++++++ src/arch/arm/tlb.cc | 10 ++- src/arch/arm/utility.cc | 47 ++++++++++- src/arch/arm/utility.hh | 11 +++ src/dev/arm/SConscript | 36 ++++++++ src/dev/arm/Versatile.py | 51 ++++++++++++ src/dev/arm/versatile.cc | 122 +++++++++++++++++++++++++++ src/dev/arm/versatile.hh | 108 ++++++++++++++++++++++++ 18 files changed, 939 insertions(+), 18 deletions(-) create mode 100644 build_opts/ARM_FS create mode 100644 src/arch/arm/ArmInterrupts.py create mode 100644 src/arch/arm/ArmSystem.py create mode 100644 src/arch/arm/interrupts.cc create mode 100644 src/arch/arm/interrupts.hh create mode 100644 src/arch/arm/kernel_stats.hh create mode 100644 src/arch/arm/stacktrace.cc create mode 100644 src/arch/arm/system.cc create mode 100644 src/arch/arm/system.hh create mode 100644 src/dev/arm/SConscript create mode 100644 src/dev/arm/Versatile.py create mode 100644 src/dev/arm/versatile.cc create mode 100644 src/dev/arm/versatile.hh diff --git a/build_opts/ARM_FS b/build_opts/ARM_FS new file mode 100644 index 0000000000..508bad76eb --- /dev/null +++ b/build_opts/ARM_FS @@ -0,0 +1,3 @@ +TARGET_ISA = 'arm' +CPU_MODELS = 'AtomicSimpleCPU,TimingSimpleCPU' +FULL_SYSTEM = 1 diff --git a/src/arch/arm/ArmInterrupts.py b/src/arch/arm/ArmInterrupts.py new file mode 100644 index 0000000000..f21d49e958 --- /dev/null +++ b/src/arch/arm/ArmInterrupts.py @@ -0,0 +1,33 @@ +# Copyright (c) 2009 ARM Limited +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ali Saidi + +from m5.SimObject import SimObject + +class ArmInterrupts(SimObject): + type = 'ArmInterrupts' + cxx_class = 'ArmISA::Interrupts' diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py new file mode 100644 index 0000000000..872776c694 --- /dev/null +++ b/src/arch/arm/ArmSystem.py @@ -0,0 +1,35 @@ +# Copyright (c) 2009 ARM Limited +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ali Saidi + +from m5.params import * + +from System import System + +class ArmSystem(System): + type = 'ArmSystem' + diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index f5fe1727c3..92a4193f12 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -1,6 +1,7 @@ # -*- mode:python -*- # Copyright (c) 2007-2008 The Florida State University +# Copyright (c) 2009 ARM Limited # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,6 +28,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Stephen Hines +# Ali Saidi Import('*') @@ -43,6 +45,7 @@ if env['TARGET_ISA'] == 'arm': Source('pagetable.cc') Source('tlb.cc') Source('vtophys.cc') + Source('utility.cc') SimObject('ArmNativeTrace.py') SimObject('ArmTLB.py') @@ -50,8 +53,12 @@ if env['TARGET_ISA'] == 'arm': TraceFlag('Arm') TraceFlag('Faults', "Trace Exceptions, interrupts, svc/swi") if env['FULL_SYSTEM']: - #Insert Full-System Files Here - pass + Source('interrupts.cc') + Source('stacktrace.cc') + Source('system.cc') + + SimObject('ArmInterrupts.py') + SimObject('ArmSystem.py') else: Source('process.cc') Source('linux/linux.cc') diff --git a/src/arch/arm/interrupts.cc b/src/arch/arm/interrupts.cc new file mode 100644 index 0000000000..a47ebc75d4 --- /dev/null +++ b/src/arch/arm/interrupts.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +#include "arch/arm/interrupts.hh" + +ArmISA::Interrupts * +ArmInterruptsParams::create() +{ + return new ArmISA::Interrupts(this); +} diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh new file mode 100644 index 0000000000..189341d6bd --- /dev/null +++ b/src/arch/arm/interrupts.hh @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +#ifndef __ARCH_ARM_INTERRUPT_HH__ +#define __ARCH_ARM_INTERRUPT_HH__ + +#include "arch/arm/faults.hh" +#include "arch/arm/isa_traits.hh" +#include "arch/arm/registers.hh" +#include "cpu/thread_context.hh" +#include "params/ArmInterrupts.hh" +#include "sim/sim_object.hh" + +namespace ArmISA +{ + +class Interrupts : public SimObject +{ + private: + BaseCPU * cpu; + + uint64_t intStatus; + + public: + + void + setCPU(BaseCPU * _cpu) + { + cpu = _cpu; + } + + typedef ArmInterruptsParams Params; + + const Params * + params() const + { + return dynamic_cast(_params); + } + + Interrupts(Params * p) : SimObject(p), cpu(NULL) + { + clearAll(); + } + + + void + post(int int_num, int index) + { + } + + void + clear(int int_num, int index) + { + } + + void + clearAll() + { + intStatus = 0; + } + + bool + checkInterrupts(ThreadContext *tc) const + { + return intStatus; + } + + Fault + getInterrupt(ThreadContext *tc) + { + warn_once("ARM Interrupts not handled\n"); + return NoFault; + } + + void + updateIntrInfo(ThreadContext *tc) + { + + } + + void + serialize(std::ostream &os) + { + } + + void + unserialize(Checkpoint *cp, const std::string §ion) + { + } +}; +} // namespace ARM_ISA + +#endif // __ARCH_ARM_INTERRUPT_HH__ diff --git a/src/arch/arm/kernel_stats.hh b/src/arch/arm/kernel_stats.hh new file mode 100644 index 0000000000..18bdc500dc --- /dev/null +++ b/src/arch/arm/kernel_stats.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_ARM_KERNEL_STATS_HH__ +#define __ARCH_ARM_KERNEL_STATS_HH__ + +#include +#include +#include +#include + +#include "kern/kernel_stats.hh" + +namespace ArmISA { +namespace Kernel { + +enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num }; +extern const char *modestr[]; + +class Statistics : public ::Kernel::Statistics +{ + public: + Statistics(System *system) : ::Kernel::Statistics(system) + {} +}; + +} /* end namespace ArmISA::Kernel */ +} /* end namespace ArmISA */ + +#endif // __ARCH_ARM_KERNEL_STATS_HH__ diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc new file mode 100644 index 0000000000..6b346b0abf --- /dev/null +++ b/src/arch/arm/stacktrace.cc @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#include + +#include "arch/arm/isa_traits.hh" +#include "arch/arm/stacktrace.hh" +#include "arch/arm/vtophys.hh" +#include "base/bitfield.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" +#include "sim/system.hh" + +using namespace std; +namespace ArmISA +{ + ProcessInfo::ProcessInfo(ThreadContext *_tc) + : tc(_tc) + { + Addr addr = 0; + + VirtualPort *vp; + + vp = tc->getVirtPort(); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) + panic("thread info not compiled into kernel\n"); + thread_info_size = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) + panic("thread info not compiled into kernel\n"); + task_struct_size = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) + panic("thread info not compiled into kernel\n"); + task_off = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) + panic("thread info not compiled into kernel\n"); + pid_off = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) + panic("thread info not compiled into kernel\n"); + name_off = vp->readGtoH(addr); + } + + Addr + ProcessInfo::task(Addr ksp) const + { + return 0; + } + + int + ProcessInfo::pid(Addr ksp) const + { + return -1; + } + + string + ProcessInfo::name(Addr ksp) const + { + return "Implement me"; + } + + StackTrace::StackTrace() + : tc(0), stack(64) + { + } + + StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) + : tc(0), stack(64) + { + trace(_tc, inst); + } + + StackTrace::~StackTrace() + { + } + + void + StackTrace::trace(ThreadContext *_tc, bool is_call) + { + } + + bool + StackTrace::isEntry(Addr addr) + { + return false; + } + + bool + StackTrace::decodeStack(MachInst inst, int &disp) + { + return false; + } + + bool + StackTrace::decodeSave(MachInst inst, int ®, int &disp) + { + return false; + } + + /* + * Decode the function prologue for the function we're in, and note + * which registers are stored where, and how large the stack frame is. + */ + bool + StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, + int &size, Addr &ra) + { + return false; + } + +#if TRACING_ON + void + StackTrace::dump() + { + DPRINTFN("------ Stack ------\n"); + + DPRINTFN(" Not implemented\n"); + } +#endif +} diff --git a/src/arch/arm/stacktrace.hh b/src/arch/arm/stacktrace.hh index c5225455c5..05fdb9e785 100644 --- a/src/arch/arm/stacktrace.hh +++ b/src/arch/arm/stacktrace.hh @@ -1,6 +1,5 @@ /* * Copyright (c) 2005 The Regents of The University of Michigan - * Copyright (c) 2007-2008 The Florida State University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,23 +25,21 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Ali Saidi - * Stephen Hines + * Authors: Nathan Binkert */ #ifndef __ARCH_ARM_STACKTRACE_HH__ #define __ARCH_ARM_STACKTRACE_HH__ #include "base/trace.hh" -#include "config/the_isa.hh" #include "cpu/static_inst.hh" class ThreadContext; -class StackTrace; - namespace ArmISA { +class StackTrace; + class ProcessInfo { private: @@ -65,7 +62,7 @@ class ProcessInfo class StackTrace { protected: - typedef TheISA::MachInst MachInst; + typedef ArmISA::MachInst MachInst; private: ThreadContext *tc; std::vector stack; @@ -95,10 +92,6 @@ class StackTrace public: const std::vector &getstack() const { return stack; } - static const int user = 1; - static const int console = 2; - static const int unknown = 3; - #if TRACING_ON private: void dump(); @@ -124,6 +117,6 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) return true; } -} +} // Namespace ArmISA #endif // __ARCH_ARM_STACKTRACE_HH__ diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc new file mode 100644 index 0000000000..e7470f89a0 --- /dev/null +++ b/src/arch/arm/system.cc @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2002-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +#include "arch/arm/system.hh" + + +using namespace LittleEndianGuest; + +ArmSystem::ArmSystem(Params *p) + : System(p) +{ + +} + +ArmSystem::~ArmSystem() +{ +} + + +ArmSystem * +ArmSystemParams::create() +{ + return new ArmSystem(this); +} diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh new file mode 100644 index 0000000000..9dfb66fb77 --- /dev/null +++ b/src/arch/arm/system.hh @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +#ifndef __ARCH_ARM_SYSTEM_HH__ +#define __ARCH_ARM_SYSTEM_HH__ + +#include +#include + +#include "params/ArmSystem.hh" +#include "sim/sim_object.hh" +#include "sim/system.hh" + +class ArmSystem : public System +{ + public: + typedef ArmSystemParams Params; + ArmSystem(Params *p); + ~ArmSystem(); + + virtual Addr fixFuncEventAddr(Addr addr) + { + //XXX This may eventually have to do something useful. + return addr; + } +}; + +#endif + diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index febc6d0812..864c061a25 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -287,7 +287,15 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) return NoFault; #else - fatal("translate atomic not yet implemented\n"); + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + if (!sctlr.m) { + req->setPaddr(req->getVaddr()); + return NoFault; + } + panic("MMU translation not implemented\n"); + return NoFault; + + #endif } diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index 8cfa48e18c..afff97d316 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -1,6 +1,37 @@ +/* + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ -#include -#include + +#include "arch/arm/faults.hh" +#include "arch/arm/utility.hh" +#include "cpu/thread_context.hh" namespace ArmISA { @@ -12,8 +43,18 @@ initCPU(ThreadContext *tc, int cpuId) // FPEXC.EN = 0 - static Fault reset = new Reset(); + static Fault reset = new Reset; if (cpuId == 0) reset->invoke(tc); } +uint64_t getArgument(ThreadContext *tc, int number, bool fp) { +#if FULL_SYSTEM + panic("getArgument() not implemented for ARM!\n"); +#else + panic("getArgument() only implemented for FULL_SYSTEM\n"); + M5_DUMMY_RETURN +#endif +} + +} diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index a2f0ef170d..43e7b14ab0 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -125,6 +125,17 @@ namespace ArmISA { { panic("Copy Misc. Regs Not Implemented Yet\n"); } + + void initCPU(ThreadContext *tc, int cpuId); + + static inline bool + inUserMode(ThreadContext *tc) + { + return (tc->readMiscRegNoEffect(MISCREG_CPSR) & 0x1f) == MODE_USER; + } + +uint64_t getArgument(ThreadContext *tc, int number, bool fp); + }; diff --git a/src/dev/arm/SConscript b/src/dev/arm/SConscript new file mode 100644 index 0000000000..dd1d73e1ac --- /dev/null +++ b/src/dev/arm/SConscript @@ -0,0 +1,36 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 ARM Limited +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ali Saidi + +Import('*') + +if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'arm': + SimObject('Versatile.py') + + Source('versatile.cc') diff --git a/src/dev/arm/Versatile.py b/src/dev/arm/Versatile.py new file mode 100644 index 0000000000..7f36bbcf3a --- /dev/null +++ b/src/dev/arm/Versatile.py @@ -0,0 +1,51 @@ +# Copyright (c) 2006-2007 The Regents of The University of Michigan +# Copyright (c) 2009 ARM Limited +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.params import * +from m5.proxy import * +from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr +from Platform import Platform +from Terminal import Terminal +from Uart import Uart8250 + + +class Versatile(Platform): + type = 'Versatile' + system = Param.System(Parent.any, "system") + + # Attach I/O devices that are on chip + def attachOnChipIO(self, bus): + pass + + + # Attach I/O devices to specified bus object. Can't do this + # earlier, since the bus object itself is typically defined at the + # System level. + def attachIO(self, bus): + pass diff --git a/src/dev/arm/versatile.cc b/src/dev/arm/versatile.cc new file mode 100644 index 0000000000..7d571db996 --- /dev/null +++ b/src/dev/arm/versatile.cc @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** @file + * Implementation of Versatile platform. + */ + +#include +#include +#include + +#include "config/the_isa.hh" +#include "cpu/intr_control.hh" +#include "dev/arm/versatile.hh" +#include "dev/terminal.hh" +#include "sim/system.hh" + +using namespace std; +using namespace TheISA; + +Versatile::Versatile(const Params *p) + : Platform(p), system(p->system) +{ + // set the back pointer from the system to myself + system->platform = this; +} + +Tick +Versatile::intrFrequency() +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +void +Versatile::postConsoleInt() +{ + warn_once("Don't know what interrupt to post for console.\n"); + //panic("Need implementation\n"); +} + +void +Versatile::clearConsoleInt() +{ + warn_once("Don't know what interrupt to clear for console.\n"); + //panic("Need implementation\n"); +} + +void +Versatile::postPciInt(int line) +{ + panic("Need implementation\n"); +} + +void +Versatile::clearPciInt(int line) +{ + panic("Need implementation\n"); +} + +Addr +Versatile::pciToDma(Addr pciAddr) const +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + + +Addr +Versatile::calcPciConfigAddr(int bus, int dev, int func) +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +Addr +Versatile::calcPciIOAddr(Addr addr) +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +Addr +Versatile::calcPciMemAddr(Addr addr) +{ + panic("Need implementation\n"); + M5_DUMMY_RETURN +} + +Versatile * +VersatileParams::create() +{ + return new Versatile(this); +} diff --git a/src/dev/arm/versatile.hh b/src/dev/arm/versatile.hh new file mode 100644 index 0000000000..edec3631ca --- /dev/null +++ b/src/dev/arm/versatile.hh @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** + * @file + * Declaration of top level class for the Versatile platform chips. This class just + * retains pointers to all its children so the children can communicate. + */ + +#ifndef __DEV_ARM_VERSATILE_HH__ +#define __DEV_ARM_VERSATILE_HH__ + +#include "dev/platform.hh" +#include "params/Versatile.hh" + +class IdeController; +class System; + +class Versatile : public Platform +{ + public: + /** Pointer to the system */ + System *system; + + public: + typedef VersatileParams Params; + /** + * Constructor for the Tsunami Class. + * @param name name of the object + * @param s system the object belongs to + * @param intctrl pointer to the interrupt controller + */ + Versatile(const Params *p); + + /** + * Return the interrupting frequency to AlphaAccess + * @return frequency of RTC interrupts + */ + virtual Tick intrFrequency(); + + /** + * Cause the cpu to post a serial interrupt to the CPU. + */ + virtual void postConsoleInt(); + + /** + * Clear a posted CPU interrupt + */ + virtual void clearConsoleInt(); + + /** + * Cause the chipset to post a cpi interrupt to the CPU. + */ + virtual void postPciInt(int line); + + /** + * Clear a posted PCI->CPU interrupt + */ + virtual void clearPciInt(int line); + + + virtual Addr pciToDma(Addr pciAddr) const; + + /** + * Calculate the configuration address given a bus/dev/func. + */ + virtual Addr calcPciConfigAddr(int bus, int dev, int func); + + /** + * Calculate the address for an IO location on the PCI bus. + */ + virtual Addr calcPciIOAddr(Addr addr); + + /** + * Calculate the address for a memory location on the PCI bus. + */ + virtual Addr calcPciMemAddr(Addr addr); +}; + +#endif // __DEV_ARM_VERSATILE_HH__ From 0916c376a97dacf5d11589cfea084f0e7feda4cf Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 17 Nov 2009 18:02:08 -0600 Subject: [PATCH 120/160] ARM: Differentiate between LDM exception return and LDM user regs. --- src/arch/arm/isa/formats/macromem.isa | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 068b48199d..c834c22cb4 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -210,7 +210,9 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0); unsigned reg = 0; - bool forceUser = machInst.puswl.psruser; + bool force_user = machInst.puswl.psruser & !OPCODE_15; + bool exception_ret = machInst.puswl.psruser & OPCODE_15; + for (int i = 1; i < ones + 1; i++) { // Find the next register. while (!bits(regs, reg)) @@ -218,12 +220,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) replaceBits(regs, reg, 0); unsigned regIdx = reg; - if (forceUser) { + if (force_user) { regIdx = intRegForceUser(regIdx); } if (machInst.puswl.loadOp) { - if (reg == INTREG_PC && forceUser) { + if (reg == INTREG_PC && exception_ret) { // This must be the exception return form of ldm. microOps[i] = new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr); From 422f0d9f10c6c3899be5992f9e5555598d4de0d2 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 17 Nov 2009 18:02:09 -0600 Subject: [PATCH 121/160] ARM: Begin implementing CP15 --- src/arch/arm/insts/static_inst.cc | 1 + src/arch/arm/isa/bitfields.isa | 1 + src/arch/arm/isa/decoder.isa | 51 ++++++++++++++++++++++++++++--- src/arch/arm/types.hh | 1 + src/arch/arm/utility.cc | 16 ++++++++++ src/arch/arm/utility.hh | 3 ++ 6 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index 5181041d03..bf7a38c582 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -27,6 +27,7 @@ * Authors: Stephen Hines */ +#include "arch/arm/faults.hh" #include "arch/arm/insts/static_inst.hh" #include "base/condcodes.hh" #include "base/cprintf.hh" diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index bd4cfc3203..8ff819983d 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -49,6 +49,7 @@ def bitfield OPCODE_18 opcode18; def bitfield OPCODE_15_12 opcode15_12; def bitfield OPCODE_15 opcode15; def bitfield MISC_OPCODE miscOpcode; +def bitfield OPC2 opc2; def bitfield OPCODE_7 opcode7; def bitfield OPCODE_4 opcode4; diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 5a6e8773a8..ff20c61075 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -493,10 +493,53 @@ format DataOp { } } // MEDIA_OPCODE (MISC_OPCODE 0x1) } // MISC_OPCODE (CPNUM 0xA) - 0xf: decode OPCODE_20 { - 0: WarnUnimpl::mcr_cp15(); - 1: WarnUnimpl::mrc_cp15(); - } + 0xf: decode RN { + // Barrriers, Cache Maintence, NOPS + 7: decode OPCODE_23_21 { + 0: decode RM { + 0: decode OPC2 { + 4: decode OPCODE_20 { + 0: PredOp::mcr_cp15_nop1({{ }}); // was wfi + } + } + 1: WarnUnimpl::cp15_cache_maint(); + 4: WarnUnimpl::cp15_par(); + 5: decode OPC2 { + 0,1: WarnUnimpl::cp15_cache_maint2(); + 4: PredOp::cp15_isb({{ ; }}, IsMemBarrier, IsSerializeBefore); + 6,7: WarnUnimpl::cp15_bp_maint(); + } + 6: WarnUnimpl::cp15_cache_maint3(); + 8: WarnUnimpl::cp15_va_to_pa(); + 10: decode OPC2 { + 1,2: WarnUnimpl::cp15_cache_maint3(); + 4: PredOp::cp15_dsb({{ ; }}, IsMemBarrier, IsSerializeBefore); + 5: PredOp::cp15_dmb({{ ; }}, IsMemBarrier, IsSerializeBefore); + } + 11: WarnUnimpl::cp15_cache_maint4(); + 13: decode OPC2 { + 1: decode OPCODE_20 { + 0: PredOp::mcr_cp15_nop2({{ }}); // was prefetch + } + } + 14: WarnUnimpl::cp15_cache_maint5(); + } // RM + } // OPCODE_23_21 CR + + // Thread ID and context ID registers + // Thread ID register needs cheaper access than miscreg + 13: WarnUnimpl::mcr_mrc_cp15_c7(); + + // All the rest + default: decode OPCODE_20 { + 0: PredOp::mcr_cp15({{ + fault = setCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2); + }}); + 1: PredOp::mrc_cp15({{ + fault = readCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2); + }}); + } + } // RN } // CPNUM (OP4 == 1) } //OPCODE_4 diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 07fa33ea17..e0b3951b99 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -58,6 +58,7 @@ namespace ArmISA Bitfield<15, 12> opcode15_12; Bitfield<15> opcode15; Bitfield<7, 4> miscOpcode; + Bitfield<7,5> opc2; Bitfield<7> opcode7; Bitfield<4> opcode4; diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index afff97d316..5ce32542bc 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -57,4 +57,20 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) { #endif } +Fault +setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2) +{ + return new UnimpFault(csprintf("MCR CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n", + CRn, opc1, CRm, opc2)); +} + +Fault +readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2) +{ + return new UnimpFault(csprintf("MRC CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n", + CRn, opc1, CRm, opc2)); + +} + + } diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 43e7b14ab0..3ddfd12dd9 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -135,6 +135,9 @@ namespace ArmISA { } uint64_t getArgument(ThreadContext *tc, int number, bool fp); + +Fault setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2); +Fault readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2); }; From c3204421d88013d1fd14eb6f642373b2b3893fbc Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:57 -0800 Subject: [PATCH 122/160] ruby: Ruby memtest python script. --- configs/example/memtest-ruby.py | 119 ++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 configs/example/memtest-ruby.py diff --git a/configs/example/memtest-ruby.py b/configs/example/memtest-ruby.py new file mode 100644 index 0000000000..0305a30964 --- /dev/null +++ b/configs/example/memtest-ruby.py @@ -0,0 +1,119 @@ +# Copyright (c) 2006-2007 The Regents of The University of Michigan +# Copyright (c) 2009 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ron Dreslinski +# Brad Beckmann + +import m5 +from m5.objects import * +from m5.defines import buildEnv +from m5.util import addToPath +import os, optparse, sys +addToPath('../common') +addToPath('../../tests/configs/') +import ruby_config + +parser = optparse.OptionParser() + +parser.add_option("-a", "--atomic", action="store_true", + help="Use atomic (non-timing) mode") +parser.add_option("-b", "--blocking", action="store_true", + help="Use blocking caches") +parser.add_option("-l", "--maxloads", metavar="N", default=0, + help="Stop after N loads") +parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick, + metavar="T", + help="Stop after T ticks") + +parser.add_option("-t", "--testers", type="int", metavar="N", default=1, + help="number of testers/cores") + +parser.add_option("-f", "--functional", type="int", default=0, + metavar="PCT", + help="Target percentage of functional accesses " + "[default: %default]") +parser.add_option("-u", "--uncacheable", type="int", default=0, + metavar="PCT", + help="Target percentage of uncacheable accesses " + "[default: %default]") + +parser.add_option("--progress", type="int", default=1000, + metavar="NLOADS", + help="Progress message interval " + "[default: %default]") + +(options, args) = parser.parse_args() + +if args: + print "Error: script doesn't take any positional arguments" + sys.exit(1) + +block_size = 64 + +if options.testers > block_size: + print "Error: Number of testers %d limited to %d because of false sharing" \ + % (options.testers, block_size) + sys.exit(1) + +cpus = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, \ + percent_functional=options.functional, \ + percent_uncacheable=options.uncacheable, \ + progress_interval=options.progress) \ + for i in xrange(options.testers) ] + +# create the desired simulated system +# ruby memory +ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", options.testers) + +system = System(cpu = cpus, funcmem = PhysicalMemory(), + physmem = ruby_memory) + +for cpu in cpus: + cpu.test = system.physmem.port + cpu.functional = system.funcmem.port + + +# ----------------------- +# run simulation +# ----------------------- + +root = Root( system = system ) +if options.atomic: + root.system.mem_mode = 'atomic' +else: + root.system.mem_mode = 'timing' + +# Not much point in this being higher than the L1 latency +m5.ticks.setGlobalFrequency('1ns') + +# instantiate configuration +m5.instantiate(root) + +# simulate until program terminates +exit_event = m5.simulate(options.maxtick) + +print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause() From 5492f71755d71ba47f3510e51510b1bbe96b743a Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:57 -0800 Subject: [PATCH 123/160] ruby: Ruby debug print fixes. --- src/mem/ruby/common/Debug.cc | 31 +++++++++++++++++++++---------- src/mem/ruby/common/Debug.hh | 1 + 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc index 1115152f44..cb9fdf0824 100644 --- a/src/mem/ruby/common/Debug.cc +++ b/src/mem/ruby/common/Debug.cc @@ -39,6 +39,7 @@ #include "mem/ruby/common/Debug.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/gems_common/util.hh" +#include "base/misc.hh" class Debug; extern Debug* g_debug_ptr; @@ -70,6 +71,7 @@ DebugComponentData debugComponents[] = {"Cache", 'c' }, {"Predictor", 'p' }, {"Allocator", 'a' }, + {"Memory", 'M' }, }; extern "C" void changeDebugVerbosity(VerbosityLevel vb); @@ -95,19 +97,27 @@ Debug::Debug() Debug::Debug( const string & name, const vector & argv ) { - for (size_t i=0;i Date: Wed, 18 Nov 2009 13:55:57 -0800 Subject: [PATCH 124/160] ruby: Ruby destruction fix. --- src/mem/ruby/common/DataBlock.hh | 6 +++++- src/mem/ruby/common/NetDest.hh | 2 +- src/mem/ruby/network/simple/SimpleNetwork.cc | 2 +- src/mem/rubymem.cc | 7 ++++--- src/mem/rubymem.hh | 3 +++ 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/mem/ruby/common/DataBlock.hh b/src/mem/ruby/common/DataBlock.hh index 3c8ef56f45..1d399753ed 100644 --- a/src/mem/ruby/common/DataBlock.hh +++ b/src/mem/ruby/common/DataBlock.hh @@ -45,7 +45,11 @@ class DataBlock { } // Destructor - ~DataBlock() { if(m_alloc) delete [] m_data;} + ~DataBlock() { + if(m_alloc) { + delete [] m_data; + } + } DataBlock& operator=(const DataBlock& obj); diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh index 1dcee7b7ae..7301409ceb 100644 --- a/src/mem/ruby/common/NetDest.hh +++ b/src/mem/ruby/common/NetDest.hh @@ -63,7 +63,7 @@ public: NetDest& operator=(const Set& obj); // Destructor - // ~NetDest(); + ~NetDest() { DEBUG_MSG(MEMORY_COMP, LowPrio, "NetDest Destructor"); } // Public Methods void add(MachineID newElement); diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc index 497c602d13..1a45340ed0 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.cc +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc @@ -124,7 +124,7 @@ SimpleNetwork::~SimpleNetwork() } m_switch_ptr_vector.deletePointers(); m_buffers_to_free.deletePointers(); - delete m_topology_ptr; + // delete m_topology_ptr; } // From a switch to an endpoint node diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index 2fb529e12d..14b2048a04 100644 --- a/src/mem/rubymem.cc +++ b/src/mem/rubymem.cc @@ -60,7 +60,7 @@ RubyMemory::RubyMemory(const Params *p) vector sys_conf; while (!config.eof()) { - char buffer[4096]; + char buffer[65536]; config.getline(buffer, sizeof(buffer)); string line = buffer; if (line.empty()) @@ -119,8 +119,8 @@ RubyMemory::init() } //Print stats at exit - RubyExitCallback* rc = new RubyExitCallback(this); - registerExitCallback(rc); + rubyExitCB = new RubyExitCallback(this); + registerExitCallback(rubyExitCB); //Sched RubyEvent, automatically reschedules to advance ruby cycles rubyTickEvent = new RubyEvent(this); @@ -138,6 +138,7 @@ RubyMemory::tick() RubyMemory::~RubyMemory() { + delete g_system_ptr; } void diff --git a/src/mem/rubymem.hh b/src/mem/rubymem.hh index e33418a424..1bfb135e8c 100644 --- a/src/mem/rubymem.hh +++ b/src/mem/rubymem.hh @@ -40,6 +40,8 @@ #include "mem/ruby/system/RubyPort.hh" #include "params/RubyMemory.hh" +class RubyExitCallback; + class RubyMemory : public PhysicalMemory { public: @@ -119,6 +121,7 @@ class RubyMemory : public PhysicalMemory private: Tick ruby_clock; Tick ruby_phase; + RubyExitCallback* rubyExitCB; public: static std::map pending_requests; From 17e14efa7e7358f02f2664e10e4001faf6b7811e Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:57 -0800 Subject: [PATCH 125/160] ruby: Ruby 64-bit address output fixes. --- src/mem/ruby/libruby.cc | 6 ++++++ src/mem/ruby/libruby.hh | 2 ++ src/mem/ruby/system/Sequencer.cc | 8 ++++++-- src/mem/ruby/system/Sequencer.hh | 2 ++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/mem/ruby/libruby.cc b/src/mem/ruby/libruby.cc index e4e302ebab..b9a72d071d 100644 --- a/src/mem/ruby/libruby.cc +++ b/src/mem/ruby/libruby.cc @@ -66,6 +66,12 @@ ostream& operator<<(ostream& out, const RubyRequestType& obj) return out; } +ostream& operator<<(std::ostream& out, const RubyRequest& obj) +{ + out << hex << "0x" << obj.paddr << flush; + return out; +} + vector tokenizeString(string str, string delims) { vector tokens; diff --git a/src/mem/ruby/libruby.hh b/src/mem/ruby/libruby.hh index a73ff5cf40..29aac232a5 100644 --- a/src/mem/ruby/libruby.hh +++ b/src/mem/ruby/libruby.hh @@ -39,6 +39,8 @@ struct RubyRequest { {} }; +std::ostream& operator<<(std::ostream& out, const RubyRequest& obj); + /** * Initialize the system. cfg_file is a Ruby-lang configuration script */ diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 780c1128e5..c693e0f37c 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -44,6 +44,10 @@ //Sequencer::Sequencer(int core_id, MessageBuffer* mandatory_q) #define LLSC_FAIL -2 +ostream& operator<<(std::ostream& out, const SequencerRequest& obj) { + out << obj.ruby_request << flush; + return out; +} Sequencer::Sequencer(const string & name) :RubyPort(name) @@ -106,7 +110,7 @@ void Sequencer::wakeup() { SequencerRequest* request = m_readRequestTable.lookup(keys[i]); if (current_time - request->issue_time >= m_deadlock_threshold) { WARN_MSG("Possible Deadlock detected"); - WARN_EXPR(request); + WARN_EXPR(request->ruby_request); WARN_EXPR(m_version); WARN_EXPR(keys.size()); WARN_EXPR(current_time); @@ -121,7 +125,7 @@ void Sequencer::wakeup() { SequencerRequest* request = m_writeRequestTable.lookup(keys[i]); if (current_time - request->issue_time >= m_deadlock_threshold) { WARN_MSG("Possible Deadlock detected"); - WARN_EXPR(request); + WARN_EXPR(request->ruby_request); WARN_EXPR(m_version); WARN_EXPR(current_time); WARN_EXPR(request->issue_time); diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh index 2b1f023c59..cf12c2a0bb 100644 --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -63,6 +63,8 @@ struct SequencerRequest { {} }; +std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj); + class Sequencer : public Consumer, public RubyPort { public: // Constructors From d7a4f665ed72b221e8210cc79bbd8edf967a4a4a Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:57 -0800 Subject: [PATCH 126/160] ruby: Added more info to bridge error message --- src/mem/bridge.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index cc9b83d3ee..d0135fc9d1 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -93,7 +93,9 @@ Bridge::init() fatal("Both ports of bus bridge are not connected to a bus.\n"); if (portA.peerBlockSize() != portB.peerBlockSize()) - fatal("Busses don't have the same block size... Not supported.\n"); + fatal("port A size %d, port B size %d \n " \ + "Busses don't have the same block size... Not supported.\n", + portA.peerBlockSize(), portB.peerBlockSize()); } bool From 3cf24f9716eebab8c24fa645d02c636584033514 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 127/160] ruby: Support for merging ALPHA_FS and ruby Connects M5 cpu and dma ports directly to ruby sequencers and dma sequencers. Rubymem also includes a pio port so that pio requests and be forwarded to a special pio bus connecting to device pio ports. --- configs/common/FSConfig.py | 44 ++++ configs/example/ruby_fs.py | 182 +++++++++++++++ src/mem/RubyMemory.py | 4 +- src/mem/SConscript | 1 + src/mem/ruby/config/MI_example-homogeneous.rb | 3 + src/mem/ruby/system/System.hh | 5 +- src/mem/rubymem.cc | 214 +++++++++++++++--- src/mem/rubymem.hh | 24 +- tests/configs/ruby_config.py | 14 +- 9 files changed, 449 insertions(+), 42 deletions(-) create mode 100644 configs/example/ruby_fs.py diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index bd20a2bacc..7ab7319cda 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -79,6 +79,50 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None): return self +def makeLinuxAlphaRubySystem(mem_mode, rubymem, mdesc = None): + class BaseTsunami(Tsunami): + ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0) + ide = IdeController(disks=[Parent.disk0, Parent.disk2], + pci_func=0, pci_dev=0, pci_bus=0) + + + self = LinuxAlphaSystem(physmem = rubymem) + if not mdesc: + # generic system + mdesc = SysConfig() + self.readfile = mdesc.script() + + # Create pio bus to connect all device pio ports to rubymem's pio port + self.piobus = Bus(bus_id=0) + + self.disk0 = CowIdeDisk(driveID='master') + self.disk2 = CowIdeDisk(driveID='master') + self.disk0.childImage(mdesc.disk()) + self.disk2.childImage(disk('linux-bigswap2.img')) + self.tsunami = BaseTsunami() + self.tsunami.attachIO(self.piobus) + self.tsunami.ide.pio = self.piobus.port + self.tsunami.ethernet.pio = self.piobus.port + + # connect the dma ports directly to ruby dma ports + self.tsunami.ide.dma = self.physmem.dma_port + self.tsunami.ethernet.dma = self.physmem.dma_port + + # connect the pio bus to rubymem + self.physmem.pio_port = self.piobus.port + + self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(), + read_only = True)) + self.intrctrl = IntrControl() + self.mem_mode = mem_mode + self.terminal = Terminal() + self.kernel = binary('vmlinux') + self.pal = binary('ts_osfpal') + self.console = binary('console') + self.boot_osflags = 'root=/dev/hda1 console=ttyS0' + + return self + def makeSparcSystem(mem_mode, mdesc = None): class CowMmDisk(MmDisk): image = CowDiskImage(child=RawDiskImage(read_only=True), diff --git a/configs/example/ruby_fs.py b/configs/example/ruby_fs.py new file mode 100644 index 0000000000..d27eae596e --- /dev/null +++ b/configs/example/ruby_fs.py @@ -0,0 +1,182 @@ +# Copyright (c) 2009 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Brad Beckmann + +# +# Full system configuraiton for ruby +# + +import os +import optparse +import sys +from os.path import join as joinpath + +import m5 +from m5.defines import buildEnv +from m5.objects import * +from m5.util import addToPath, panic + +if not buildEnv['FULL_SYSTEM']: + panic("This script requires full-system mode (*_FS).") + +addToPath('../../tests/configs/') +addToPath('../common') + +import ruby_config + +from FSConfig import * +from SysPaths import * +from Benchmarks import * +import Simulation +from Caches import * + +# Get paths we might need. It's expected this file is in m5/configs/example. +config_path = os.path.dirname(os.path.abspath(__file__)) +config_root = os.path.dirname(config_path) +m5_root = os.path.dirname(config_root) + +parser = optparse.OptionParser() + +# Benchmark options +parser.add_option("-b", "--benchmark", action="store", type="string", + dest="benchmark", + help="Specify the benchmark to run. Available benchmarks: %s"\ + % DefinedBenchmarks) +parser.add_option("-o", "--options", default="", + help='The options to pass to the binary, use " " around the entire string') +parser.add_option("-i", "--input", default="", help="Read stdin from a file.") +parser.add_option("--output", default="", help="Redirect stdout to a file.") +parser.add_option("--errout", default="", help="Redirect stderr to a file.") +parser.add_option("--ruby-debug", action="store_true") +parser.add_option("--ruby-debug-file", default="", help="Ruby debug out file (stdout if blank)") + +# ruby host memory experimentation +parser.add_option("--cache_size", type="int") +parser.add_option("--cache_assoc", type="int") +parser.add_option("--map_levels", type="int") + +execfile(os.path.join(config_root, "common", "Options.py")) + +(options, args) = parser.parse_args() + +if args: + print "Error: script doesn't take any positional arguments" + sys.exit(1) + +if options.benchmark: + try: + bm = Benchmarks[options.benchmark] + except KeyError: + print "Error benchmark %s has not been defined." % options.benchmark + print "Valid benchmarks are: %s" % DefinedBenchmarks + sys.exit(1) +else: + bm = [SysConfig()] + +# +# currently ruby fs only works in timing mode because ruby does not support +# atomic accesses by devices +# +assert(options.timing) + +(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) + +CPUClass.clock = '1GHz' + +# +# Since we are running in timing mode, set the number of M5 ticks to ruby ticks +# to the cpu clock frequency +# +M5_to_ruby_tick = '1000t' + +np = options.num_cpus + +# check for max instruction count +if options.max_inst: + max_inst = options.max_inst +else: + max_inst = 0 + +# set cache size +if options.cache_size: + cache_size = options.cache_size +else: + cache_size = 32768 # 32 kB is default + +# set cache assoc +if options.cache_assoc: + cache_assoc = options.cache_assoc +else: + cache_assoc = 8 # 8 is default + +# set map levels +if options.map_levels: + map_levels = options.map_levels +else: + map_levels = 4 # 4 levels is the default + +# +# Currently, since ruby configuraiton is separate from m5, we need to manually +# tell ruby that two dma ports are created by makeLinuxAlphaRubySystem(). +# Eventually, this will be fix with a unified configuration system. +# +rubymem = ruby_config.generate("MI_example-homogeneous.rb", + np, + np, + 128, + False, + cache_size, + cache_assoc, + map_levels, + 2, + M5_to_ruby_tick) + +if options.ruby_debug == True: + rubymem.debug = True + rubymem.debug_file = options.ruby_debug_file + +system = makeLinuxAlphaRubySystem(test_mem_mode, rubymem, bm[0]) + +system.cpu = [CPUClass(cpu_id=i) for i in xrange(np)] + +if options.l2cache: + print "Error: -l2cache incompatible with ruby, must configure it ruby-style" + sys.exit(1) + +if options.caches: + print "Error: -caches incompatible with ruby, must configure it ruby-style" + sys.exit(1) + +for i in xrange(np): + system.cpu[i].connectMemPorts(system.physmem) + + if options.fastmem: + system.cpu[i].physmem_port = system.physmem.port + +root = Root(system = system) + +Simulation.run(options, root, system, FutureClass) diff --git a/src/mem/RubyMemory.py b/src/mem/RubyMemory.py index fbbbeebe49..ddd97572c5 100644 --- a/src/mem/RubyMemory.py +++ b/src/mem/RubyMemory.py @@ -42,4 +42,6 @@ class RubyMemory(PhysicalMemory): debug = Param.Bool(False, "Use ruby debug") debug_file = Param.String("ruby.debug", "path to the Ruby debug output file (stdout if blank)") - + num_dmas = Param.Int(0, "Number of DMA ports connected to the Ruby memory") + dma_port = VectorPort("Ruby_dma_ports") + pio_port = Port("Ruby_pio_port") diff --git a/src/mem/SConscript b/src/mem/SConscript index 21335a709a..2188850e09 100644 --- a/src/mem/SConscript +++ b/src/mem/SConscript @@ -63,3 +63,4 @@ TraceFlag('BusBridge') TraceFlag('LLSC') TraceFlag('MMU') TraceFlag('MemoryAccess') +TraceFlag('Ruby') diff --git a/src/mem/ruby/config/MI_example-homogeneous.rb b/src/mem/ruby/config/MI_example-homogeneous.rb index 2b416e647a..b7842aaafe 100644 --- a/src/mem/ruby/config/MI_example-homogeneous.rb +++ b/src/mem/ruby/config/MI_example-homogeneous.rb @@ -37,6 +37,9 @@ for i in 0..$*.size-1 do elsif $*[i] == "-s" memory_size_mb = $*[i+1].to_i i = i + 1 + elsif $*[i] == "-D" + num_dma = $*[i+1].to_i + i = i + 1 end end diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh index 38ef091775..1d36de878f 100644 --- a/src/mem/ruby/system/System.hh +++ b/src/mem/ruby/system/System.hh @@ -107,7 +107,10 @@ public: if (m_ports.count(name) != 1){ cerr << "Port " << name << " has " << m_ports.count(name) << " instances" << endl; } - assert(m_ports.count(name) == 1); m_ports[name]->registerHitCallback(hit_callback); return m_ports[name]; } + assert(m_ports.count(name) == 1); + m_ports[name]->registerHitCallback(hit_callback); + return m_ports[name]; + } static Network* getNetwork() { assert(m_network_ptr != NULL); return m_network_ptr; } static Topology* getTopology(const string & name) { assert(m_topologies.count(name) == 1); return m_topologies[name]; } static CacheMemory* getCache(const string & name) { assert(m_caches.count(name) == 1); return m_caches[name]; } diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index 14b2048a04..70077e7da5 100644 --- a/src/mem/rubymem.cc +++ b/src/mem/rubymem.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,6 +27,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Daniel Sanchez + * Brad Beckmann */ #include @@ -63,6 +65,7 @@ RubyMemory::RubyMemory(const Params *p) char buffer[65536]; config.getline(buffer, sizeof(buffer)); string line = buffer; + DPRINTF(Ruby, "%s %d\n", line, line.empty()); if (line.empty()) continue; vector tokens; @@ -81,11 +84,27 @@ RubyMemory::RubyMemory(const Params *p) RubySystem::create(sys_conf); + // + // Create the necessary ruby_ports to connect to the sequencers. + // This code should be fixed when the configuration systems are unified + // and the ruby configuration text files no longer exist. Also, + // it would be great to remove the single ruby_hit_callback func with + // separate pointers to particular ports to rubymem. However, functional + // access currently prevent the improvement. + // for (int i = 0; i < params()->num_cpus; i++) { RubyPort *p = RubySystem::getPort(csprintf("Sequencer_%d", i), ruby_hit_callback); ruby_ports.push_back(p); } + + for (int i = 0; i < params()->num_dmas; i++) { + RubyPort *p = RubySystem::getPort(csprintf("DMASequencer_%d", i), + ruby_hit_callback); + ruby_dma_ports.push_back(p); + } + + pio_port = NULL; } void @@ -106,7 +125,6 @@ RubyMemory::init() //g_debug_ptr->setDebugTime(1); //g_debug_ptr->setDebugOutputFile("ruby.debug"); - g_system_ptr->clearStats(); if (ports.size() == 0) { @@ -118,6 +136,15 @@ RubyMemory::init() (*pi)->sendStatusChange(Port::RangeChange); } + for (PortIterator pi = dma_ports.begin(); pi != dma_ports.end(); ++pi) { + if (*pi) + (*pi)->sendStatusChange(Port::RangeChange); + } + + if (pio_port != NULL) { + pio_port->sendStatusChange(Port::RangeChange); + } + //Print stats at exit rubyExitCB = new RubyExitCallback(this); registerExitCallback(rubyExitCB); @@ -141,35 +168,45 @@ RubyMemory::~RubyMemory() delete g_system_ptr; } -void -RubyMemory::hitCallback(PacketPtr pkt, Port *port) -{ - DPRINTF(MemoryAccess, "Hit callback\n"); - - bool needsResponse = pkt->needsResponse(); - doAtomicAccess(pkt); - - // turn packet around to go back to requester if response expected - if (needsResponse) { - // recvAtomic() should already have turned packet into - // atomic response - assert(pkt->isResponse()); - DPRINTF(MemoryAccess, "Sending packet back over port\n"); - port->sendTiming(pkt); - } else { - delete pkt; - } - DPRINTF(MemoryAccess, "Hit callback done!\n"); -} - Port * RubyMemory::getPort(const std::string &if_name, int idx) { + DPRINTF(Ruby, "getting port %d %s\n", idx, if_name); + DPRINTF(Ruby, + "number of ruby ports %d and dma ports %d\n", + ruby_ports.size(), + ruby_dma_ports.size()); + // Accept request for "functional" port for backwards compatibility // with places where this function is called from C++. I'd prefer // to move all these into Python someday. if (if_name == "functional") { - return new Port(csprintf("%s-functional", name()), this); + return new Port(csprintf("%s-functional", name()), + this, + ruby_ports[idx]); + } + + // + // if dma port request, allocate the appropriate prot + // + if (if_name == "dma_port") { + assert(idx < ruby_dma_ports.size()); + RubyMemory::Port* dma_port = + new Port(csprintf("%s-dma_port%d", name(), idx), + this, + ruby_dma_ports[idx]); + dma_ports.push_back(dma_port); + return dma_port; + } + + // + // if pio port, ensure that there is only one + // + if (if_name == "pio_port") { + assert(pio_port == NULL); + pio_port = + new RubyMemory::Port("ruby_pio_port", this, NULL); + return pio_port; } if (if_name != "port") { @@ -184,30 +221,68 @@ RubyMemory::getPort(const std::string &if_name, int idx) panic("RubyMemory::getPort: port %d already assigned", idx); } - Port *port = new Port(csprintf("%s-port%d", name(), idx), this); + // + // Currently this code assumes that each cpu has both a + // icache and dcache port and therefore divides by two. This will be + // fixed once we unify the configuration systems and Ruby sequencers + // directly support M5 ports. + // + assert(idx/2 < ruby_ports.size()); + Port *port = new Port(csprintf("%s-port%d", name(), idx), + this, + ruby_ports[idx/2]); ports[idx] = port; return port; } -RubyMemory::Port::Port(const std::string &_name, RubyMemory *_memory) +RubyMemory::Port::Port(const std::string &_name, + RubyMemory *_memory, + RubyPort *_port) : PhysicalMemory::MemoryPort::MemoryPort(_name, _memory) { + DPRINTF(Ruby, "creating port to ruby memory %s\n", _name); ruby_mem = _memory; + ruby_port = _port; } bool RubyMemory::Port::recvTiming(PacketPtr pkt) { - DPRINTF(MemoryAccess, "Timing access caught\n"); + DPRINTF(MemoryAccess, + "Timing access caught for address %#x\n", + pkt->getAddr()); //dsm: based on SimpleTimingPort::recvTiming(pkt); - // If the device is only a slave, it should only be sending - // responses, which should never get nacked. There used to be - // code to hanldle nacks here, but I'm pretty sure it didn't work - // correctly with the drain code, so that would need to be fixed - // if we ever added it back. + // + // In FS mode, ruby memory will receive pio responses from devices and + // it must forward these responses back to the particular CPU. + // + if (pkt->isResponse() != false && isPioAddress(pkt->getAddr()) != false) { + DPRINTF(MemoryAccess, + "Pio Response callback %#x\n", + pkt->getAddr()); + RubyMemory::SenderState *senderState = + safe_cast(pkt->senderState); + RubyMemory::Port *port = senderState->port; + + // pop the sender state from the packet + pkt->senderState = senderState->saved; + delete senderState; + + port->sendTiming(pkt); + + return true; + } + + // + // After checking for pio responses, the remainder of packets + // received by ruby should only be M5 requests, which should never + // get nacked. There used to be code to hanldle nacks here, but + // I'm pretty sure it didn't work correctly with the drain code, + // so that would need to be fixed if we ever added it back. + // assert(pkt->isRequest()); if (pkt->memInhibitAsserted()) { @@ -221,6 +296,18 @@ RubyMemory::Port::recvTiming(PacketPtr pkt) // Save the port in the sender state object pkt->senderState = new SenderState(this, pkt->senderState); + // + // Check for pio requests and directly send them to the dedicated + // pio_port. + // + if (isPioAddress(pkt->getAddr()) != false) { + return ruby_mem->pio_port->sendTiming(pkt); + } + + // + // For DMA and CPU requests, translate them to ruby requests before + // sending them to our assigned ruby port. + // RubyRequestType type = RubyRequestType_NULL; Addr pc = 0; if (pkt->isRead()) { @@ -241,7 +328,6 @@ RubyMemory::Port::recvTiming(PacketPtr pkt) RubyAccessMode_Supervisor); // Submit the ruby request - RubyPort *ruby_port = ruby_mem->ruby_ports[pkt->req->contextId()]; int64_t req_id = ruby_port->makeRequest(ruby_request); if (req_id == -1) { RubyMemory::SenderState *senderState = @@ -262,6 +348,12 @@ RubyMemory::Port::recvTiming(PacketPtr pkt) void ruby_hit_callback(int64_t req_id) { + // + // Note: This single fuction can be called by cpu and dma ports, + // as well as the functional port. The functional port prevents + // us from replacing this single function with separate port + // functions. + // typedef map map_t; map_t &prm = RubyMemory::pending_requests; @@ -280,13 +372,58 @@ ruby_hit_callback(int64_t req_id) pkt->senderState = senderState->saved; delete senderState; - port->ruby_mem->hitCallback(pkt, port); + port->hitCallback(pkt); } void +RubyMemory::Port::hitCallback(PacketPtr pkt) +{ + + bool needsResponse = pkt->needsResponse(); + + DPRINTF(MemoryAccess, "Hit callback needs response %d\n", + needsResponse); + + ruby_mem->doAtomicAccess(pkt); + + // turn packet around to go back to requester if response expected + if (needsResponse) { + // recvAtomic() should already have turned packet into + // atomic response + assert(pkt->isResponse()); + DPRINTF(MemoryAccess, "Sending packet back over port\n"); + sendTiming(pkt); + } else { + delete pkt; + } + DPRINTF(MemoryAccess, "Hit callback done!\n"); +} + +bool RubyMemory::Port::sendTiming(PacketPtr pkt) { schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0 + return true; +} + +bool +RubyMemory::Port::isPioAddress(Addr addr) +{ + AddrRangeList pioAddrList; + bool snoop = false; + if (ruby_mem->pio_port == NULL) { + return false; + } + + ruby_mem->pio_port->getPeerAddressRanges(pioAddrList, snoop); + for(AddrRangeIter iter = pioAddrList.begin(); iter != pioAddrList.end(); iter++) { + if (addr >= iter->start && addr <= iter->end) { + DPRINTF(MemoryAccess, "Pio request found in %#llx - %#llx range\n", + iter->start, iter->end); + return true; + } + } + return false; } void RubyMemory::printConfigStats() @@ -313,6 +450,17 @@ void RubyMemory::printConfig(std::ostream & out) const { //g_system_ptr->printConfig(out); } +void RubyMemory::serialize(ostream &os) +{ + PhysicalMemory::serialize(os); +} + +void RubyMemory::unserialize(Checkpoint *cp, const string §ion) +{ + DPRINTF(Config, "Ruby memory being restored\n"); + reschedule(rubyTickEvent, curTick + ruby_clock + ruby_phase); + PhysicalMemory::unserialize(cp, section); +} //Python-interface code RubyMemory * diff --git a/src/mem/rubymem.hh b/src/mem/rubymem.hh index 1bfb135e8c..dd0a492f5b 100644 --- a/src/mem/rubymem.hh +++ b/src/mem/rubymem.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,6 +40,7 @@ #include "mem/physical.hh" #include "mem/ruby/system/RubyPort.hh" #include "params/RubyMemory.hh" +#include "mem/port.hh" class RubyExitCallback; @@ -46,18 +48,26 @@ class RubyMemory : public PhysicalMemory { public: std::vector ruby_ports; + std::vector ruby_dma_ports; class Port : public MemoryPort { friend void ruby_hit_callback(int64_t req_id); RubyMemory *ruby_mem; + RubyPort *ruby_port; public: - Port(const std::string &_name, RubyMemory *_memory); - void sendTiming(PacketPtr pkt); + Port(const std::string &_name, + RubyMemory *_memory, + RubyPort *_port); + bool sendTiming(PacketPtr pkt); + void hitCallback(PacketPtr pkt); protected: virtual bool recvTiming(PacketPtr pkt); + + private: + bool isPioAddress(Addr addr); }; class RubyEvent : public Event @@ -110,8 +120,6 @@ class RubyMemory : public PhysicalMemory //options change & M5 determines the //stats file to use - void hitCallback(PacketPtr pkt, Port *port); - void printStats(std::ostream & out) const; void clearStats(); void printConfig(std::ostream & out) const; @@ -125,6 +133,14 @@ class RubyMemory : public PhysicalMemory public: static std::map pending_requests; + RubyMemory::Port* pio_port; + + protected: + std::vector dma_ports; + + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; void ruby_hit_callback(int64_t); diff --git a/tests/configs/ruby_config.py b/tests/configs/ruby_config.py index 7b8e276136..000b7d23f9 100644 --- a/tests/configs/ruby_config.py +++ b/tests/configs/ruby_config.py @@ -4,17 +4,25 @@ import subprocess from os.path import dirname, join as joinpath import m5 +from m5.params import * -def generate(config_file, cores=1, memories=1, memory_size=1024): +def generate(config_file, cores=1, memories=1, memory_size=1024, \ + cache_size=32768, cache_assoc=8, dmas=1, + ruby_tick='1t'): default = joinpath(dirname(__file__), '../../src/mem/ruby/config') ruby_config = os.environ.get('RUBY_CONFIG', default) args = [ "ruby", "-I", ruby_config, joinpath(ruby_config, "print_cfg.rb"), "-r", joinpath(ruby_config, config_file), "-p", str(cores), - "-m", str(memories), "-s", str(memory_size)] + "-m", str(memories), "-s", str(memory_size), "-C", str(cache_size), + "-A", str(cache_assoc), "-D", str(dmas)] temp_config = joinpath(m5.options.outdir, "ruby.config") ret = subprocess.call(args, stdout=file(temp_config, "w")) if ret != 0: raise RuntimeError, "subprocess failed!" - return m5.objects.RubyMemory(config_file=temp_config, num_cpus=cores) + return m5.objects.RubyMemory(clock = ruby_tick, + config_file = temp_config, + num_cpus = cores, + range = AddrRange(str(memory_size)+"MB"), + num_dmas = dmas) From dce53610c374eba2a8dae236a13b3197cd42edc6 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 128/160] ruby: Added error check for openning the ruby config file --- src/mem/rubymem.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index 70077e7da5..aecc0af32f 100644 --- a/src/mem/rubymem.cc +++ b/src/mem/rubymem.cc @@ -58,8 +58,15 @@ RubyMemory::RubyMemory(const Params *p) ruby_clock = p->clock; ruby_phase = p->phase; + DPRINTF(Ruby, "creating Ruby Memory from file %s\n", + p->config_file.c_str()); + ifstream config(p->config_file.c_str()); + if (config.good() == false) { + fatal("Did not successfully open %s.\n", p->config_file.c_str()); + } + vector sys_conf; while (!config.eof()) { char buffer[65536]; From 90d6e2652fc8590116d436a1143700e11893cfa4 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 129/160] ruby: included ruby config parameter ports per core Slightly improved the major hack need to correctly assign the number of ports per core. CPUs have two ports: icache + dcache. MemTester has one port. --- configs/example/memtest-ruby.py | 7 +++++-- src/mem/RubyMemory.py | 1 + src/mem/rubymem.cc | 10 ++++++---- src/mem/rubymem.hh | 1 + tests/configs/ruby_config.py | 5 +++-- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/configs/example/memtest-ruby.py b/configs/example/memtest-ruby.py index 0305a30964..e47b8e0a3d 100644 --- a/configs/example/memtest-ruby.py +++ b/configs/example/memtest-ruby.py @@ -86,8 +86,11 @@ cpus = [ MemTest(atomic=options.atomic, max_loads=options.maxloads, \ for i in xrange(options.testers) ] # create the desired simulated system -# ruby memory -ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", options.testers) +# ruby memory must be at least 16 MB to work with the mem tester +ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", + cores = options.testers, + memory_size = 16, + ports_per_cpu = 1) system = System(cpu = cpus, funcmem = PhysicalMemory(), physmem = ruby_memory) diff --git a/src/mem/RubyMemory.py b/src/mem/RubyMemory.py index ddd97572c5..2ad794a3f9 100644 --- a/src/mem/RubyMemory.py +++ b/src/mem/RubyMemory.py @@ -45,3 +45,4 @@ class RubyMemory(PhysicalMemory): num_dmas = Param.Int(0, "Number of DMA ports connected to the Ruby memory") dma_port = VectorPort("Ruby_dma_ports") pio_port = Port("Ruby_pio_port") + ports_per_core = Param.Int(2, "Number of per core. Typical two: icache + dcache") diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index aecc0af32f..9a1a7927d5 100644 --- a/src/mem/rubymem.cc +++ b/src/mem/rubymem.cc @@ -58,6 +58,8 @@ RubyMemory::RubyMemory(const Params *p) ruby_clock = p->clock; ruby_phase = p->phase; + ports_per_cpu = p->ports_per_core; + DPRINTF(Ruby, "creating Ruby Memory from file %s\n", p->config_file.c_str()); @@ -230,14 +232,14 @@ RubyMemory::getPort(const std::string &if_name, int idx) // // Currently this code assumes that each cpu has both a - // icache and dcache port and therefore divides by two. This will be - // fixed once we unify the configuration systems and Ruby sequencers + // icache and dcache port and therefore divides by ports per cpu. This will + // be fixed once we unify the configuration systems and Ruby sequencers // directly support M5 ports. // - assert(idx/2 < ruby_ports.size()); + assert(idx/ports_per_cpu < ruby_ports.size()); Port *port = new Port(csprintf("%s-port%d", name(), idx), this, - ruby_ports[idx/2]); + ruby_ports[idx/ports_per_cpu]); ports[idx] = port; return port; diff --git a/src/mem/rubymem.hh b/src/mem/rubymem.hh index dd0a492f5b..2672dcb77c 100644 --- a/src/mem/rubymem.hh +++ b/src/mem/rubymem.hh @@ -130,6 +130,7 @@ class RubyMemory : public PhysicalMemory Tick ruby_clock; Tick ruby_phase; RubyExitCallback* rubyExitCB; + int ports_per_cpu; public: static std::map pending_requests; diff --git a/tests/configs/ruby_config.py b/tests/configs/ruby_config.py index 000b7d23f9..fec7bd36c2 100644 --- a/tests/configs/ruby_config.py +++ b/tests/configs/ruby_config.py @@ -8,7 +8,7 @@ from m5.params import * def generate(config_file, cores=1, memories=1, memory_size=1024, \ cache_size=32768, cache_assoc=8, dmas=1, - ruby_tick='1t'): + ruby_tick='1t', ports_per_cpu=2): default = joinpath(dirname(__file__), '../../src/mem/ruby/config') ruby_config = os.environ.get('RUBY_CONFIG', default) args = [ "ruby", "-I", ruby_config, joinpath(ruby_config, "print_cfg.rb"), @@ -25,4 +25,5 @@ def generate(config_file, cores=1, memories=1, memory_size=1024, \ config_file = temp_config, num_cpus = cores, range = AddrRange(str(memory_size)+"MB"), - num_dmas = dmas) + num_dmas = dmas, + ports_per_core = ports_per_cpu) From 6e1dc2546cfe0c6da08b57cd8478c28820277890 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 130/160] m5: Added isValidSrc and isValidDest calls to packet.hh --- src/mem/packet.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 07c086cd51..c588622702 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -437,6 +437,7 @@ class Packet : public FastAlloc, public Printable bool hadBadAddress() const { return cmd == MemCmd::BadAddressError; } void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; } + bool isSrcValid() { return flags.isSet(VALID_SRC); } /// Accessor function to get the source index of the packet. NodeID getSrc() const { assert(flags.isSet(VALID_SRC)); return src; } /// Accessor function to set the source index of the packet. @@ -444,6 +445,7 @@ class Packet : public FastAlloc, public Printable /// Reset source field, e.g. to retransmit packet on different bus. void clearSrc() { flags.clear(VALID_SRC); } + bool isDestValid() { return flags.isSet(VALID_DST); } /// Accessor function for the destination index of the packet. NodeID getDest() const { assert(flags.isSet(VALID_DST)); return dest; } /// Accessor function to set the destination index of the packet. From b8c413e99325faf54182e34413ece8ed0e4e0592 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 131/160] m5: Moved profile option since Simulation depends on it. --- configs/common/Options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/common/Options.py b/configs/common/Options.py index 1da831e1f7..2d4aedcae3 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -62,6 +62,7 @@ parser.add_option("-s", "--standard-switch", action="store_true", parser.add_option("-w", "--warmup", action="store", type="int", help="if -s, then this is the warmup period. else, this is ignored", default=5000000000) +parser.add_option("--profile", help="CPU profile interval") # Fastforwarding and simpoint related materials parser.add_option("-W", "--warmup-insts", action="store", type="int", From 204d1776caa17329b84e5ebbe50fca4f1e80c100 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 132/160] ruby: Fixed Directory memory destructor --- src/mem/ruby/system/DirectoryMemory.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc index c87be94a23..e230059ad1 100644 --- a/src/mem/ruby/system/DirectoryMemory.cc +++ b/src/mem/ruby/system/DirectoryMemory.cc @@ -84,11 +84,14 @@ void DirectoryMemory::init(const vector & argv) DirectoryMemory::~DirectoryMemory() { // free up all the directory entries - for (int i=0;i Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 133/160] ruby: getPort function fix Fixed RubyMemory::getPort function to not pass in a -1 for the idx parameter --- src/mem/rubymem.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index 9a1a7927d5..74a6e390ef 100644 --- a/src/mem/rubymem.cc +++ b/src/mem/rubymem.cc @@ -186,10 +186,19 @@ RubyMemory::getPort(const std::string &if_name, int idx) ruby_ports.size(), ruby_dma_ports.size()); + // + // By default, getPort will be passed an idx of -1. Of course this is an + // invalid ruby port index and must be a modified + // + if (idx == -1) { + idx = 0; + } + // Accept request for "functional" port for backwards compatibility // with places where this function is called from C++. I'd prefer // to move all these into Python someday. if (if_name == "functional") { + assert(idx < ruby_ports.size()); return new Port(csprintf("%s-functional", name()), this, ruby_ports[idx]); From 4d731a522dba6d4c8146bfce3633142b48ec50b6 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 134/160] m5: fixed destructor to deschedule the tickEvent and event --- src/dev/mc146818.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dev/mc146818.cc b/src/dev/mc146818.cc index 0bb6558c81..2e6ed2a4b9 100644 --- a/src/dev/mc146818.cc +++ b/src/dev/mc146818.cc @@ -105,6 +105,8 @@ MC146818::MC146818(EventManager *em, const string &n, const struct tm time, MC146818::~MC146818() { + deschedule(tickEvent); + deschedule(event); } void From f54790977b319a3dafdc58c3ff4a0c28780bad4c Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 135/160] m5: removed master and slave deletions. The unresolved destructor call caused a seg fault when called. --- src/dev/ide_ctrl.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dev/ide_ctrl.cc b/src/dev/ide_ctrl.cc index a8cceda1f4..87dc0b2aa9 100644 --- a/src/dev/ide_ctrl.cc +++ b/src/dev/ide_ctrl.cc @@ -75,8 +75,6 @@ IdeController::Channel::Channel( IdeController::Channel::~Channel() { - delete master; - delete slave; } IdeController::IdeController(Params *p) From faf1d97f2447f0e3b9dce9fb06e9e87e496333a3 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 136/160] ruby: fixed dma mi example to work with multiple dma ports --- src/mem/protocol/MI_example-dir.sm | 24 +++++++++++++++--------- src/mem/protocol/MI_example-dma.sm | 2 ++ src/mem/protocol/MI_example-msg.sm | 1 + src/mem/ruby/config/MI_example.rb | 2 -- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm index c045419b6a..0061a2838b 100644 --- a/src/mem/protocol/MI_example-dir.sm +++ b/src/mem/protocol/MI_example-dir.sm @@ -1,8 +1,6 @@ machine(Directory, "Directory protocol") -: int directory_latency, - int dma_select_low_bit, - int dma_select_num_bits +: int directory_latency { MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false"; @@ -74,6 +72,7 @@ machine(Directory, "Directory protocol") State TBEState, desc="Transient State"; DataBlock DataBlk, desc="Data to be written (DMA write only)"; int Len, desc="..."; + MachineID DmaRequestor, desc="DMA requestor"; } external_type(TBETable) { @@ -243,8 +242,7 @@ machine(Directory, "Directory protocol") out_msg.LineAddress := address; out_msg.Type := DMAResponseType:DATA; out_msg.DataBlk := in_msg.DataBlk; // we send the entire data block and rely on the dma controller to split it up if need be - out_msg.Destination.add(mapAddressToRange(address, MachineType:DMA, - dma_select_low_bit, dma_select_num_bits)); + out_msg.Destination.add(TBEs[address].DmaRequestor); out_msg.MessageSize := MessageSizeType:Response_Data; } } @@ -259,8 +257,7 @@ machine(Directory, "Directory protocol") out_msg.LineAddress := address; out_msg.Type := DMAResponseType:DATA; out_msg.DataBlk := in_msg.DataBlk; // we send the entire data block and rely on the dma controller to split it up if need be - out_msg.Destination.add(mapAddressToRange(address, MachineType:DMA, - dma_select_low_bit, dma_select_num_bits)); + out_msg.Destination.add(TBEs[address].DmaRequestor); out_msg.MessageSize := MessageSizeType:Response_Data; } } @@ -271,8 +268,7 @@ machine(Directory, "Directory protocol") out_msg.PhysicalAddress := address; out_msg.LineAddress := address; out_msg.Type := DMAResponseType:ACK; - out_msg.Destination.add(mapAddressToRange(address, MachineType:DMA, - dma_select_low_bit, dma_select_num_bits)); + out_msg.Destination.add(TBEs[address].DmaRequestor); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -343,6 +339,14 @@ machine(Directory, "Directory protocol") TBEs[address].DataBlk := in_msg.DataBlk; TBEs[address].PhysicalAddress := in_msg.PhysicalAddress; TBEs[address].Len := in_msg.Len; + TBEs[address].DmaRequestor := in_msg.Requestor; + } + } + + action(r_allocateTbeForDmaRead, "\r", desc="Allocate TBE for DMA Read") { + peek(dmaRequestQueue_in, DMARequestMsg) { + TBEs.allocate(address); + TBEs[address].DmaRequestor := in_msg.Requestor; } } @@ -485,6 +489,7 @@ machine(Directory, "Directory protocol") transition(I, DMA_READ, ID) { //dr_sendDMAData; + r_allocateTbeForDmaRead; qf_queueMemoryFetchRequestDMA; p_popIncomingDMARequestQueue; } @@ -492,6 +497,7 @@ machine(Directory, "Directory protocol") transition(ID, Memory_Data, I) { dr_sendDMAData; //p_popIncomingDMARequestQueue; + w_deallocateTBE; l_popMemQueue; } diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm index e883288df9..0f4894b3a1 100644 --- a/src/mem/protocol/MI_example-dma.sm +++ b/src/mem/protocol/MI_example-dma.sm @@ -71,6 +71,7 @@ machine(DMA, "DMA Controller") out_msg.PhysicalAddress := in_msg.PhysicalAddress; out_msg.LineAddress := in_msg.LineAddress; out_msg.Type := DMARequestType:READ; + out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; out_msg.Destination.add(map_Address_to_Directory(address)); @@ -85,6 +86,7 @@ machine(DMA, "DMA Controller") out_msg.PhysicalAddress := in_msg.PhysicalAddress; out_msg.LineAddress := in_msg.LineAddress; out_msg.Type := DMARequestType:WRITE; + out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; out_msg.Destination.add(map_Address_to_Directory(address)); diff --git a/src/mem/protocol/MI_example-msg.sm b/src/mem/protocol/MI_example-msg.sm index d4d5572003..3cdb74e492 100644 --- a/src/mem/protocol/MI_example-msg.sm +++ b/src/mem/protocol/MI_example-msg.sm @@ -105,6 +105,7 @@ structure(DMARequestMsg, desc="...", interface="NetworkMessage") { DMARequestType Type, desc="Request type (read/write)"; Address PhysicalAddress, desc="Physical address for this request"; Address LineAddress, desc="Line address for this request"; + MachineID Requestor, desc="Node who initiated the request"; NetDest Destination, desc="Destination"; DataBlock DataBlk, desc="DataBlk attached to this request"; int Len, desc="The length of the request"; diff --git a/src/mem/ruby/config/MI_example.rb b/src/mem/ruby/config/MI_example.rb index 187dc7a687..8113087aa6 100644 --- a/src/mem/ruby/config/MI_example.rb +++ b/src/mem/ruby/config/MI_example.rb @@ -23,8 +23,6 @@ class MI_example_DirectoryController < DirectoryController def argv() vec = super() vec += " directory_latency "+directory_latency.to_s - vec += " dma_select_low_bit "+log_int(RubySystem.block_size_bytes).to_s - vec += " dma_select_num_bits "+log_int(NetPort.totalOfType("DMA")).to_s end end From b5d2052fa0b7c62372e1b936f2654f700e831b68 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 137/160] m5: Fixed bug in atomic cpu destructor --- src/cpu/simple/atomic.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index c092b5b1fd..05b4ca3e21 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -171,6 +171,9 @@ AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p) AtomicSimpleCPU::~AtomicSimpleCPU() { + if (tickEvent.scheduled()) { + deschedule(tickEvent); + } } void From 70a261c0ae297749f9bb10e4c5fbcf3562f423bf Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 138/160] m5: Added option to take a checkpoint at the end of simulation --- configs/common/Options.py | 3 +++ configs/common/Simulation.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/configs/common/Options.py b/configs/common/Options.py index 2d4aedcae3..abc26f1b5a 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -53,6 +53,9 @@ parser.add_option("--checkpoint-dir", action="store", type="string", help="Place all checkpoints in this absolute directory") parser.add_option("-r", "--checkpoint-restore", action="store", type="int", help="restore from checkpoint ") +parser.add_option("--checkpoint-at-end", action="store_true", + help="take a checkpoint at end of run") + # CPU Switching - default switch model goes from a checkpoint # to a timing simple CPU with caches to warm up, then to detailed CPU for diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index 112a951b66..1c9d4ff4eb 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -374,3 +374,6 @@ def run(options, root, testsys, cpu_class): exit_cause = exit_event.getCause() print 'Exiting @ cycle %i because %s' % (m5.curTick(), exit_cause) + if options.checkpoint_at_end: + m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) + From e84881b7a353e8a45640f7d53fa032003272656a Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 139/160] ruby: Removed unused action z_stall --- src/mem/protocol/MI_example-dma.sm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm index 0f4894b3a1..79c42e7199 100644 --- a/src/mem/protocol/MI_example-dma.sm +++ b/src/mem/protocol/MI_example-dma.sm @@ -115,10 +115,6 @@ machine(DMA, "DMA Controller") dmaResponseQueue_in.dequeue(); } - action(z_stall, "z", desc="dma is busy..stall") { - // do nothing - } - transition(READY, ReadRequest, BUSY_RD) { s_sendReadRequest; p_popRequestQueue; From cc2db929cbdb95168600de42a45a361f3a9e7318 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 140/160] ruby: slicc state machine error fixes Added error messages when: - a state does not exist in a machine's list of known states. - an event does not exist in a machine - the actions of a certain machine have not been declared --- src/mem/slicc/ast/TransitionDeclAST.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mem/slicc/ast/TransitionDeclAST.py b/src/mem/slicc/ast/TransitionDeclAST.py index ef745fd503..a941d7b0c9 100644 --- a/src/mem/slicc/ast/TransitionDeclAST.py +++ b/src/mem/slicc/ast/TransitionDeclAST.py @@ -46,9 +46,20 @@ class TransitionDeclAST(DeclAST): if machine is None: self.error("Transition declaration not part of a machine.") + for action in self.actions: + if action not in machine.actions: + self.error("Invalid action: %s is not part of machine: %s" % \ + (action, machine)) + for state in self.states: + if state not in machine.states: + self.error("Invalid state: %s is not part of machine: %s" % \ + (state, machine)) next_state = self.next_state or state for event in self.events: + if event not in machine.events: + self.error("Invalid event: %s is not part of machine: %s" % \ + (event, machine)) t = Transition(self.symtab, machine, state, event, next_state, self.actions, self.location, self.pairs) machine.addTransition(t) From 994169327a232a4325d529a7071c295fa39cf7d2 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 141/160] ruby: slicc action error fix Small fix to the State Machine error message when duplicate actions are defined. --- src/mem/slicc/symbols/StateMachine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index e54d6a435d..8583ed46b0 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -68,7 +68,7 @@ class StateMachine(Symbol): # Check for duplicate action for other in self.actions.itervalues(): if action.ident == other.ident: - a.warning("Duplicate action definition: %s" % a.ident) + action.warning("Duplicate action definition: %s" % action.ident) action.error("Duplicate action definition: %s" % action.ident) if action.short == other.short: other.warning("Duplicate action shorthand: %s" % other.ident) From ed54ecf1c8f66d544385bbaa0d5902d5af4394e3 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 142/160] ruby: slicc method error fix Added error message when a method call is not supported by an object. --- src/mem/slicc/ast/MethodCallExprAST.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py index d423ee4a7c..3f9b250c1c 100644 --- a/src/mem/slicc/ast/MethodCallExprAST.py +++ b/src/mem/slicc/ast/MethodCallExprAST.py @@ -97,6 +97,9 @@ class MemberMethodCallExprAST(MethodCallExprAST): methodId = obj_type.methodId(self.proc_name, paramTypes) prefix = "" + if methodId not in obj_type.methods: + self.error("Invalid method call: Type '%s' does not have a method '%s'", + obj_type, methodId) return_type = obj_type.methods[methodId].return_type if return_type.isInterface: prefix = "static_cast<%s &>" % return_type.c_ident From 8b0f970084895dcef026e5720a1cd7c34afbc47a Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: [PATCH 143/160] ruby: Added default names to message buffers Added default names to message buffers created by the simple network. --- src/mem/ruby/buffers/MessageBuffer.cc | 24 +++----------------- src/mem/ruby/buffers/MessageBuffer.hh | 6 ++--- src/mem/ruby/network/simple/SimpleNetwork.cc | 6 +++-- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc index 3928e94e60..eaa3965474 100644 --- a/src/mem/ruby/buffers/MessageBuffer.cc +++ b/src/mem/ruby/buffers/MessageBuffer.cc @@ -34,27 +34,8 @@ #include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/system/System.hh" -MessageBuffer::MessageBuffer() -{ - m_msg_counter = 0; - m_consumer_ptr = NULL; - m_ordering_set = false; - m_strict_fifo = true; - m_size = 0; - m_max_size = -1; - m_last_arrival_time = 0; - m_randomization = true; - m_size_last_time_size_checked = 0; - m_time_last_time_size_checked = 0; - m_time_last_time_enqueue = 0; - m_time_last_time_pop = 0; - m_size_at_cycle_start = 0; - m_msgs_this_cycle = 0; - m_not_avail_count = 0; - m_priority_rank = 0; -} - -MessageBuffer::MessageBuffer(const Chip* chip_ptr) // The chip_ptr is ignored, but could be used for extra debugging +MessageBuffer::MessageBuffer(const Chip* chip_ptr, + const string &name) { m_msg_counter = 0; m_consumer_ptr = NULL; @@ -72,6 +53,7 @@ MessageBuffer::MessageBuffer(const Chip* chip_ptr) // The chip_ptr is ignored, m_msgs_this_cycle = 0; m_not_avail_count = 0; m_priority_rank = 0; + m_name = name; } int MessageBuffer::getSize() diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh index 3ca6790d06..dfb66dfdf9 100644 --- a/src/mem/ruby/buffers/MessageBuffer.hh +++ b/src/mem/ruby/buffers/MessageBuffer.hh @@ -51,10 +51,10 @@ class Chip; class MessageBuffer { public: // Constructors - MessageBuffer(); - MessageBuffer(const Chip* chip_ptr); // The chip_ptr is ignored, but could be used for extra debugging + // The chip_ptr is ignored, but could be used for extra debugging + MessageBuffer(const Chip* chip_ptr = NULL, + const string &name = ""); - // Use Default Destructor // ~MessageBuffer() // Public Methods diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc index 1a45340ed0..f6a217c917 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.cc +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc @@ -87,8 +87,10 @@ void SimpleNetwork::init(const vector & argv) m_toNetQueues[node].setSize(m_virtual_networks); m_fromNetQueues[node].setSize(m_virtual_networks); for (int j = 0; j < m_virtual_networks; j++) { - m_toNetQueues[node][j] = new MessageBuffer; - m_fromNetQueues[node][j] = new MessageBuffer; + m_toNetQueues[node][j] = new MessageBuffer(NULL, + "toNet node "+int_to_string(node)+" j "+int_to_string(j)); + m_fromNetQueues[node][j] = new MessageBuffer(NULL, + "fromNet node "+int_to_string(node)+" j "+int_to_string(j)); } } From 7ab484624faa4445f35333241c25159b352a0921 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:33:35 -0800 Subject: [PATCH 144/160] ruby: split CacheMemory.hh into a .hh and a .cc --- src/mem/ruby/system/CacheMemory.cc | 459 +++++++++++++++++++++++++++++ src/mem/ruby/system/CacheMemory.hh | 459 ----------------------------- src/mem/ruby/system/SConscript | 1 + 3 files changed, 460 insertions(+), 459 deletions(-) create mode 100644 src/mem/ruby/system/CacheMemory.cc diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc new file mode 100644 index 0000000000..8d5ba3270f --- /dev/null +++ b/src/mem/ruby/system/CacheMemory.cc @@ -0,0 +1,459 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mem/ruby/system/CacheMemory.hh" + +// Output operator declaration +//ostream& operator<<(ostream& out, const CacheMemory& obj); + +// ******************* Definitions ******************* + +// Output operator definition +ostream& operator<<(ostream& out, const CacheMemory& obj) +{ + obj.print(out); + out << flush; + return out; +} + + +// **************************************************************** + +CacheMemory::CacheMemory(const string & name) + : m_cache_name(name) +{ + m_profiler_ptr = new CacheProfiler(name); +} + +void CacheMemory::init(const vector & argv) +{ + int cache_size = 0; + string policy; + + m_controller = NULL; + for (uint32 i=0; igetName() << endl; + out << " cache_associativity: " << m_cache_assoc << endl; + out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; + const int cache_num_sets = 1 << m_cache_num_set_bits; + out << " num_cache_sets: " << cache_num_sets << endl; + out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl; + out << " cache_set_size_Kbytes: " + << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl; + out << " cache_set_size_Mbytes: " + << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl; + out << " cache_size_bytes: " + << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl; + out << " cache_size_Kbytes: " + << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl; + out << " cache_size_Mbytes: " + << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl; +} + +// PRIVATE METHODS + +// convert a Address to its location in the cache +Index CacheMemory::addressToCacheSet(const Address& address) const +{ + assert(address == line_address(address)); + return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1); +} + +// Given a cache index: returns the index of the tag in a set. +// returns -1 if the tag is not found. +int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const +{ + assert(tag == line_address(tag)); + // search the set for the tags + for (int i=0; i < m_cache_assoc; i++) { + if ((m_cache[cacheSet][i] != NULL) && + (m_cache[cacheSet][i]->m_Address == tag) && + (m_cache[cacheSet][i]->m_Permission != AccessPermission_NotPresent)) { + return i; + } + } + return -1; // Not found +} + +// Given a cache index: returns the index of the tag in a set. +// returns -1 if the tag is not found. +int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const +{ + assert(tag == line_address(tag)); + // search the set for the tags + for (int i=0; i < m_cache_assoc; i++) { + if (m_cache[cacheSet][i] != NULL && m_cache[cacheSet][i]->m_Address == tag) + return i; + } + return -1; // Not found +} + +// PUBLIC METHODS +bool CacheMemory::tryCacheAccess(const Address& address, + CacheRequestType type, + DataBlock*& data_ptr) +{ + assert(address == line_address(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + if(loc != -1){ // Do we even have a tag match? + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; + m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); + data_ptr = &(entry->getDataBlk()); + + if(entry->m_Permission == AccessPermission_Read_Write) { + return true; + } + if ((entry->m_Permission == AccessPermission_Read_Only) && + (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { + return true; + } + // The line must not be accessible + } + data_ptr = NULL; + return false; +} + +bool CacheMemory::testCacheAccess(const Address& address, + CacheRequestType type, + DataBlock*& data_ptr) +{ + assert(address == line_address(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + if(loc != -1){ // Do we even have a tag match? + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; + m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); + data_ptr = &(entry->getDataBlk()); + + return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent); + } + data_ptr = NULL; + return false; +} + +// tests to see if an address is present in the cache +bool CacheMemory::isTagPresent(const Address& address) const +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int location = findTagInSet(cacheSet, address); + + if (location == -1) { + // We didn't find the tag + DEBUG_EXPR(CACHE_COMP, LowPrio, address); + DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match"); + return false; + } + DEBUG_EXPR(CACHE_COMP, LowPrio, address); + DEBUG_MSG(CACHE_COMP, LowPrio, "found"); + return true; +} + +// Returns true if there is: +// a) a tag match on this address or there is +// b) an unused line in the same cache "way" +bool CacheMemory::cacheAvail(const Address& address) const +{ + assert(address == line_address(address)); + + Index cacheSet = addressToCacheSet(address); + + for (int i=0; i < m_cache_assoc; i++) { + AbstractCacheEntry* entry = m_cache[cacheSet][i]; + if (entry != NULL) { + if (entry->m_Address == address || // Already in the cache + entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry + return true; + } + } else { + return true; + } + } + return false; +} + +void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) +{ + assert(address == line_address(address)); + assert(!isTagPresent(address)); + assert(cacheAvail(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + + // Find the first open slot + Index cacheSet = addressToCacheSet(address); + for (int i=0; i < m_cache_assoc; i++) { + if (m_cache[cacheSet][i] == NULL || + m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) { + m_cache[cacheSet][i] = entry; // Init entry + m_cache[cacheSet][i]->m_Address = address; + m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; + m_locked[cacheSet][i] = -1; + + m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime()); + + return; + } + } + ERROR_MSG("Allocate didn't find an available entry"); +} + +void CacheMemory::deallocate(const Address& address) +{ + assert(address == line_address(address)); + assert(isTagPresent(address)); + DEBUG_EXPR(CACHE_COMP, HighPrio, address); + Index cacheSet = addressToCacheSet(address); + int location = findTagInSet(cacheSet, address); + if (location != -1){ + delete m_cache[cacheSet][location]; + m_cache[cacheSet][location] = NULL; + m_locked[cacheSet][location] = -1; + } +} + +// Returns with the physical address of the conflicting cache line +Address CacheMemory::cacheProbe(const Address& address) const +{ + assert(address == line_address(address)); + assert(!cacheAvail(address)); + + Index cacheSet = addressToCacheSet(address); + return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address; +} + +// looks an address up in the cache +AbstractCacheEntry& CacheMemory::lookup(const Address& address) +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + return *m_cache[cacheSet][loc]; +} + +// looks an address up in the cache +const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + return *m_cache[cacheSet][loc]; +} + +AccessPermission CacheMemory::getPermission(const Address& address) const +{ + assert(address == line_address(address)); + return lookup(address).m_Permission; +} + +void CacheMemory::changePermission(const Address& address, AccessPermission new_perm) +{ + assert(address == line_address(address)); + lookup(address).m_Permission = new_perm; + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + m_locked[cacheSet][loc] = -1; + assert(getPermission(address) == new_perm); +} + +// Sets the most recently used bit for a cache block +void CacheMemory::setMRU(const Address& address) +{ + Index cacheSet; + + cacheSet = addressToCacheSet(address); + m_replacementPolicy_ptr->touch(cacheSet, + findTagInSet(cacheSet, address), + g_eventQueue_ptr->getTime()); +} + +void CacheMemory::profileMiss(const CacheMsg & msg) +{ + m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(), + msg.getSize(), msg.getPrefetch()); +} + +void CacheMemory::recordCacheContents(CacheRecorder& tr) const +{ + for (int i = 0; i < m_cache_num_sets; i++) { + for (int j = 0; j < m_cache_assoc; j++) { + AccessPermission perm = m_cache[i][j]->m_Permission; + CacheRequestType request_type = CacheRequestType_NULL; + if (perm == AccessPermission_Read_Only) { + if (m_is_instruction_only_cache) { + request_type = CacheRequestType_IFETCH; + } else { + request_type = CacheRequestType_LD; + } + } else if (perm == AccessPermission_Read_Write) { + request_type = CacheRequestType_ST; + } + + if (request_type != CacheRequestType_NULL) { + // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, + // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j)); + } + } + } +} + +void CacheMemory::print(ostream& out) const +{ + out << "Cache dump: " << m_cache_name << endl; + for (int i = 0; i < m_cache_num_sets; i++) { + for (int j = 0; j < m_cache_assoc; j++) { + if (m_cache[i][j] != NULL) { + out << " Index: " << i + << " way: " << j + << " entry: " << *m_cache[i][j] << endl; + } else { + out << " Index: " << i + << " way: " << j + << " entry: NULL" << endl; + } + } + } +} + +void CacheMemory::printData(ostream& out) const +{ + out << "printData() not supported" << endl; +} + +void CacheMemory::clearStats() const +{ + m_profiler_ptr->clearStats(); +} + +void CacheMemory::printStats(ostream& out) const +{ + m_profiler_ptr->printStats(out); +} + +void CacheMemory::getMemoryValue(const Address& addr, char* value, + unsigned int size_in_bytes ){ + AbstractCacheEntry& entry = lookup(line_address(addr)); + unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); + for(unsigned int i=0; i 0); + for(unsigned int i=0; i m_all_caches; }; -// Output operator declaration -//ostream& operator<<(ostream& out, const CacheMemory& obj); - -// ******************* Definitions ******************* - -// Output operator definition -inline -ostream& operator<<(ostream& out, const CacheMemory& obj) -{ - obj.print(out); - out << flush; - return out; -} - - -// **************************************************************** - -inline -CacheMemory::CacheMemory(const string & name) - : m_cache_name(name) -{ - m_profiler_ptr = new CacheProfiler(name); -} - -inline -void CacheMemory::init(const vector & argv) -{ - int cache_size = 0; - string policy; - - m_controller = NULL; - for (uint32 i=0; igetName() << endl; - out << " cache_associativity: " << m_cache_assoc << endl; - out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; - const int cache_num_sets = 1 << m_cache_num_set_bits; - out << " num_cache_sets: " << cache_num_sets << endl; - out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl; - out << " cache_set_size_Kbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl; - out << " cache_set_size_Mbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl; - out << " cache_size_bytes: " - << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl; - out << " cache_size_Kbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl; - out << " cache_size_Mbytes: " - << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl; -} - -// PRIVATE METHODS - -// convert a Address to its location in the cache -inline -Index CacheMemory::addressToCacheSet(const Address& address) const -{ - assert(address == line_address(address)); - return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1); -} - -// Given a cache index: returns the index of the tag in a set. -// returns -1 if the tag is not found. -inline -int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const -{ - assert(tag == line_address(tag)); - // search the set for the tags - for (int i=0; i < m_cache_assoc; i++) { - if ((m_cache[cacheSet][i] != NULL) && - (m_cache[cacheSet][i]->m_Address == tag) && - (m_cache[cacheSet][i]->m_Permission != AccessPermission_NotPresent)) { - return i; - } - } - return -1; // Not found -} - -// Given a cache index: returns the index of the tag in a set. -// returns -1 if the tag is not found. -inline -int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const -{ - assert(tag == line_address(tag)); - // search the set for the tags - for (int i=0; i < m_cache_assoc; i++) { - if (m_cache[cacheSet][i] != NULL && m_cache[cacheSet][i]->m_Address == tag) - return i; - } - return -1; // Not found -} - -// PUBLIC METHODS -inline -bool CacheMemory::tryCacheAccess(const Address& address, - CacheRequestType type, - DataBlock*& data_ptr) -{ - assert(address == line_address(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - if(loc != -1){ // Do we even have a tag match? - AbstractCacheEntry* entry = m_cache[cacheSet][loc]; - m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); - data_ptr = &(entry->getDataBlk()); - - if(entry->m_Permission == AccessPermission_Read_Write) { - return true; - } - if ((entry->m_Permission == AccessPermission_Read_Only) && - (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { - return true; - } - // The line must not be accessible - } - data_ptr = NULL; - return false; -} - -inline -bool CacheMemory::testCacheAccess(const Address& address, - CacheRequestType type, - DataBlock*& data_ptr) -{ - assert(address == line_address(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - if(loc != -1){ // Do we even have a tag match? - AbstractCacheEntry* entry = m_cache[cacheSet][loc]; - m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); - data_ptr = &(entry->getDataBlk()); - - return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent); - } - data_ptr = NULL; - return false; -} - -// tests to see if an address is present in the cache -inline -bool CacheMemory::isTagPresent(const Address& address) const -{ - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int location = findTagInSet(cacheSet, address); - - if (location == -1) { - // We didn't find the tag - DEBUG_EXPR(CACHE_COMP, LowPrio, address); - DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match"); - return false; - } - DEBUG_EXPR(CACHE_COMP, LowPrio, address); - DEBUG_MSG(CACHE_COMP, LowPrio, "found"); - return true; -} - -// Returns true if there is: -// a) a tag match on this address or there is -// b) an unused line in the same cache "way" -inline -bool CacheMemory::cacheAvail(const Address& address) const -{ - assert(address == line_address(address)); - - Index cacheSet = addressToCacheSet(address); - - for (int i=0; i < m_cache_assoc; i++) { - AbstractCacheEntry* entry = m_cache[cacheSet][i]; - if (entry != NULL) { - if (entry->m_Address == address || // Already in the cache - entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry - return true; - } - } else { - return true; - } - } - return false; -} - -inline -void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) -{ - assert(address == line_address(address)); - assert(!isTagPresent(address)); - assert(cacheAvail(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - - // Find the first open slot - Index cacheSet = addressToCacheSet(address); - for (int i=0; i < m_cache_assoc; i++) { - if (m_cache[cacheSet][i] == NULL || - m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) { - m_cache[cacheSet][i] = entry; // Init entry - m_cache[cacheSet][i]->m_Address = address; - m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; - m_locked[cacheSet][i] = -1; - - m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime()); - - return; - } - } - ERROR_MSG("Allocate didn't find an available entry"); -} - -inline -void CacheMemory::deallocate(const Address& address) -{ - assert(address == line_address(address)); - assert(isTagPresent(address)); - DEBUG_EXPR(CACHE_COMP, HighPrio, address); - Index cacheSet = addressToCacheSet(address); - int location = findTagInSet(cacheSet, address); - if (location != -1){ - delete m_cache[cacheSet][location]; - m_cache[cacheSet][location] = NULL; - m_locked[cacheSet][location] = -1; - } -} - -// Returns with the physical address of the conflicting cache line -inline -Address CacheMemory::cacheProbe(const Address& address) const -{ - assert(address == line_address(address)); - assert(!cacheAvail(address)); - - Index cacheSet = addressToCacheSet(address); - return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address; -} - -// looks an address up in the cache -inline -AbstractCacheEntry& CacheMemory::lookup(const Address& address) -{ - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - return *m_cache[cacheSet][loc]; -} - -// looks an address up in the cache -inline -const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const -{ - assert(address == line_address(address)); - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - assert(loc != -1); - return *m_cache[cacheSet][loc]; -} - -inline -AccessPermission CacheMemory::getPermission(const Address& address) const -{ - assert(address == line_address(address)); - return lookup(address).m_Permission; -} - -inline -void CacheMemory::changePermission(const Address& address, AccessPermission new_perm) -{ - assert(address == line_address(address)); - lookup(address).m_Permission = new_perm; - Index cacheSet = addressToCacheSet(address); - int loc = findTagInSet(cacheSet, address); - m_locked[cacheSet][loc] = -1; - assert(getPermission(address) == new_perm); -} - -// Sets the most recently used bit for a cache block -inline -void CacheMemory::setMRU(const Address& address) -{ - Index cacheSet; - - cacheSet = addressToCacheSet(address); - m_replacementPolicy_ptr->touch(cacheSet, - findTagInSet(cacheSet, address), - g_eventQueue_ptr->getTime()); -} - -inline -void CacheMemory::profileMiss(const CacheMsg & msg) -{ - m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(), - msg.getSize(), msg.getPrefetch()); -} - -inline -void CacheMemory::recordCacheContents(CacheRecorder& tr) const -{ - for (int i = 0; i < m_cache_num_sets; i++) { - for (int j = 0; j < m_cache_assoc; j++) { - AccessPermission perm = m_cache[i][j]->m_Permission; - CacheRequestType request_type = CacheRequestType_NULL; - if (perm == AccessPermission_Read_Only) { - if (m_is_instruction_only_cache) { - request_type = CacheRequestType_IFETCH; - } else { - request_type = CacheRequestType_LD; - } - } else if (perm == AccessPermission_Read_Write) { - request_type = CacheRequestType_ST; - } - - if (request_type != CacheRequestType_NULL) { - // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, - // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j)); - } - } - } -} - -inline -void CacheMemory::print(ostream& out) const -{ - out << "Cache dump: " << m_cache_name << endl; - for (int i = 0; i < m_cache_num_sets; i++) { - for (int j = 0; j < m_cache_assoc; j++) { - if (m_cache[i][j] != NULL) { - out << " Index: " << i - << " way: " << j - << " entry: " << *m_cache[i][j] << endl; - } else { - out << " Index: " << i - << " way: " << j - << " entry: NULL" << endl; - } - } - } -} - -inline -void CacheMemory::printData(ostream& out) const -{ - out << "printData() not supported" << endl; -} - -inline void CacheMemory::clearStats() const -{ - m_profiler_ptr->clearStats(); -} - -inline -void CacheMemory::printStats(ostream& out) const -{ - m_profiler_ptr->printStats(out); -} - -inline -void CacheMemory::getMemoryValue(const Address& addr, char* value, - unsigned int size_in_bytes ){ - AbstractCacheEntry& entry = lookup(line_address(addr)); - unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); - for(unsigned int i=0; i 0); - for(unsigned int i=0; i Date: Wed, 18 Nov 2009 16:33:35 -0800 Subject: [PATCH 145/160] ruby: fix CacheMemory destructor --- src/mem/ruby/system/CacheMemory.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc index 8d5ba3270f..04adbcf696 100644 --- a/src/mem/ruby/system/CacheMemory.cc +++ b/src/mem/ruby/system/CacheMemory.cc @@ -98,6 +98,12 @@ CacheMemory::~CacheMemory() { if(m_replacementPolicy_ptr != NULL) delete m_replacementPolicy_ptr; + delete m_profiler_ptr; + for (int i = 0; i < m_cache_num_sets; i++) { + for (int j = 0; j < m_cache_assoc; j++) { + delete m_cache[i][j]; + } + } } void CacheMemory::printConfig(ostream& out) From 7b8fcecf11813492d770a0d766fb9a9fb01be3e2 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:31 -0800 Subject: [PATCH 146/160] ruby: cache configuration fix to use bytes Changed cache size to be in bytes instead of kb so that testers can use very small caches and increase the chance of writeback races. --- src/mem/ruby/config/MI_example-homogeneous.rb | 10 ++++++++-- src/mem/ruby/config/cfg.rb | 16 ++++++++-------- src/mem/ruby/system/CacheMemory.cc | 10 +++++++--- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/mem/ruby/config/MI_example-homogeneous.rb b/src/mem/ruby/config/MI_example-homogeneous.rb index b7842aaafe..1ed81ee420 100644 --- a/src/mem/ruby/config/MI_example-homogeneous.rb +++ b/src/mem/ruby/config/MI_example-homogeneous.rb @@ -13,7 +13,7 @@ RubySystem.reset # default values num_cores = 2 -l1_cache_size_kb = 32 +l1_cache_size_kb = 32768 l1_cache_assoc = 8 l1_cache_latency = 1 num_memories = 2 @@ -37,6 +37,12 @@ for i in 0..$*.size-1 do elsif $*[i] == "-s" memory_size_mb = $*[i+1].to_i i = i + 1 + elsif $*[i] == "-C" + l1_cache_size_bytes = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-A" + l1_cache_assoc = $*[i+1].to_i + i = i + 1 elsif $*[i] == "-D" num_dma = $*[i+1].to_i i = i + 1 @@ -51,7 +57,7 @@ assert(protocol == "MI_example", __FILE__ + " cannot be used with protocol " + p require protocol+".rb" num_cores.times { |n| - cache = SetAssociativeCache.new("l1u_"+n.to_s, l1_cache_size_kb, l1_cache_latency, l1_cache_assoc, "PSEUDO_LRU") + cache = SetAssociativeCache.new("l1u_"+n.to_s, l1_cache_size_bytes, l1_cache_latency, l1_cache_assoc, "PSEUDO_LRU") sequencer = Sequencer.new("Sequencer_"+n.to_s, cache, cache) iface_ports << sequencer net_ports << MI_example_CacheController.new("L1CacheController_"+n.to_s, diff --git a/src/mem/ruby/config/cfg.rb b/src/mem/ruby/config/cfg.rb index 1c261544d7..f2564e1d32 100644 --- a/src/mem/ruby/config/cfg.rb +++ b/src/mem/ruby/config/cfg.rb @@ -401,17 +401,17 @@ class DMAController < NetPort end class Cache < LibRubyObject - attr :size_kb, :latency + attr :size, :latency attr_writer :controller - def initialize(obj_name, size_kb, latency) + def initialize(obj_name, size, latency) super(obj_name) - assert size_kb.is_a?(Integer), "Cache size must be an integer" - @size_kb = size_kb + assert size.is_a?(Integer), "Cache size must be an integer" + @size = size @latency = latency end def args - "controller "+@controller.obj_name+" size_kb "+@size_kb.to_s+" latency "+@latency.to_s + "controller "+@controller.obj_name+" size "+@size.to_s+" latency "+@latency.to_s end end @@ -422,8 +422,8 @@ class SetAssociativeCache < Cache # when an integer, it represents the number of cycles for a hit # when a float, it represents the cache access time in ns # when set to "auto", libruby will attempt to find a realistic latency by running CACTI - def initialize(obj_name, size_kb, latency, assoc, replacement_policy) - super(obj_name, size_kb, latency) + def initialize(obj_name, size, latency, assoc, replacement_policy) + super(obj_name, size, latency) @assoc = assoc @replacement_policy = replacement_policy end @@ -431,7 +431,7 @@ class SetAssociativeCache < Cache def calculateLatency() if @latency == "auto" cacti_args = Array.new() - cacti_args << (@size_kb*1024) << RubySystem.block_size_bytes << @assoc + cacti_args << (@size) << RubySystem.block_size_bytes << @assoc cacti_args << 1 << 0 << 0 << 0 << 1 cacti_args << RubySystem.tech_nm << RubySystem.block_size_bytes*8 cacti_args << 0 << 0 << 0 << 1 << 0 << 0 << 0 << 0 << 1 diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc index 04adbcf696..a5c881a618 100644 --- a/src/mem/ruby/system/CacheMemory.cc +++ b/src/mem/ruby/system/CacheMemory.cc @@ -52,12 +52,12 @@ CacheMemory::CacheMemory(const string & name) void CacheMemory::init(const vector & argv) { - int cache_size = 0; + int cache_size = -1; string policy; m_controller = NULL; for (uint32 i=0; i & argv) } } - m_cache_num_sets = cache_size / m_cache_assoc; + assert(cache_size != -1); + + m_cache_num_sets = (cache_size / m_cache_assoc) / RubySystem::getBlockSizeBytes(); + assert(m_cache_num_sets > 1); m_cache_num_set_bits = log_int(m_cache_num_sets); + assert(m_cache_num_set_bits > 0); if(policy == "PSEUDO_LRU") m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); From 2783a7b9ad90d04d74418d7463c255c29ffd8046 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:31 -0800 Subject: [PATCH 147/160] ruby: returns the number of LLC needed for broadcast Added feature to CacheMemory to return the number of last level caches. This count is need for broadcast protocols such as MOESI_hammer. --- .../protocol/RubySlicc_ComponentMapping.sm | 2 + .../RubySlicc_ComponentMapping.cc | 38 +++++++++++++++++++ .../RubySlicc_ComponentMapping.hh | 11 +++++- src/mem/ruby/slicc_interface/SConscript | 1 + src/mem/ruby/system/CacheMemory.cc | 18 +++++++++ src/mem/ruby/system/CacheMemory.hh | 4 ++ 6 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc diff --git a/src/mem/protocol/RubySlicc_ComponentMapping.sm b/src/mem/protocol/RubySlicc_ComponentMapping.sm index 559e54a8c8..2a027554ed 100644 --- a/src/mem/protocol/RubySlicc_ComponentMapping.sm +++ b/src/mem/protocol/RubySlicc_ComponentMapping.sm @@ -29,6 +29,8 @@ // Mapping functions +int getNumberOfLastLevelCaches(); + // NodeID map_address_to_node(Address addr); MachineID mapAddressToRange(Address addr, MachineType type, int low, int high); MachineID map_Address_to_DMA(Address addr); diff --git a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc new file mode 100644 index 0000000000..4d37b00078 --- /dev/null +++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc @@ -0,0 +1,38 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" +#include "mem/ruby/system/CacheMemory.hh" + +int getNumberOfLastLevelCaches() +{ + return CacheMemory::numberOfLastLevelCaches(); +} + diff --git a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh index 96405c8dd7..222ff86f82 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh @@ -61,6 +61,15 @@ #define MACHINETYPE_L3CACHE_ENUM MachineType_NUM #endif +#ifdef MACHINETYPE_DMA +#define MACHINETYPE_DMA_ENUM MachineType_DMA +#else +#define MACHINETYPE_DMA_ENUM MachineType_NUM +#endif + +// used to determine the number of acks to wait for +int getNumberOfLastLevelCaches(); + // used to determine the home directory // returns a value between 0 and total_directories_within_the_system inline @@ -81,7 +90,7 @@ MachineID map_Address_to_Directory(const Address &addr) inline MachineID map_Address_to_DMA(const Address & addr) { - MachineID dma = {MachineType_DMA, 0}; + MachineID dma = {MACHINETYPE_DMA_ENUM, 0}; return dma; } diff --git a/src/mem/ruby/slicc_interface/SConscript b/src/mem/ruby/slicc_interface/SConscript index 2b20892ba6..6ba614fa98 100644 --- a/src/mem/ruby/slicc_interface/SConscript +++ b/src/mem/ruby/slicc_interface/SConscript @@ -35,3 +35,4 @@ if not env['RUBY']: Source('AbstractCacheEntry.cc') Source('RubySlicc_Profiler_interface.cc') +Source('RubySlicc_ComponentMapping.cc') diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc index a5c881a618..630b945427 100644 --- a/src/mem/ruby/system/CacheMemory.cc +++ b/src/mem/ruby/system/CacheMemory.cc @@ -28,6 +28,9 @@ #include "mem/ruby/system/CacheMemory.hh" +int CacheMemory::m_num_last_level_caches = 0; +MachineType CacheMemory::m_last_level_machine_type = MachineType_FIRST; + // Output operator declaration //ostream& operator<<(ostream& out, const CacheMemory& obj); @@ -55,6 +58,8 @@ void CacheMemory::init(const vector & argv) int cache_size = -1; string policy; + m_num_last_level_caches = + MachineType_base_count(MachineType_FIRST); m_controller = NULL; for (uint32 i=0; i & argv) policy = argv[i+1]; } else if (argv[i] == "controller") { m_controller = RubySystem::getController(argv[i+1]); + if (m_last_level_machine_type < m_controller->getMachineType()) { + m_num_last_level_caches = + MachineType_base_count(m_controller->getMachineType()); + m_last_level_machine_type = + m_controller->getMachineType(); + } } else { cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << argv[i] << endl; } @@ -110,6 +121,13 @@ CacheMemory::~CacheMemory() } } +int +CacheMemory::numberOfLastLevelCaches() +{ + return m_num_last_level_caches; +} + + void CacheMemory::printConfig(ostream& out) { out << "Cache config: " << m_cache_name << endl; diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh index 00cd8ae354..856b7bcac6 100644 --- a/src/mem/ruby/system/CacheMemory.hh +++ b/src/mem/ruby/system/CacheMemory.hh @@ -70,6 +70,8 @@ public: // static CacheMemory* createCache(int level, int num, char split_type, AbstractCacheEntry* (*entry_factory)()); // static CacheMemory* getCache(int cache_id); + static int numberOfLastLevelCaches(); + // Public Methods void printConfig(ostream& out); @@ -167,6 +169,8 @@ private: int m_cache_num_set_bits; int m_cache_assoc; + static int m_num_last_level_caches; + static MachineType m_last_level_machine_type; static Vector< CacheMemory* > m_all_caches; }; From b0973035b4db86052c1d5d67e8695bdaa27130c2 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:31 -0800 Subject: [PATCH 148/160] ruby: added the original hammer protocols from old ruby --- src/mem/protocol/MOESI_hammer-cache.sm | 1104 ++++++++++++++++++++++++ src/mem/protocol/MOESI_hammer-dir.sm | 317 +++++++ src/mem/protocol/MOESI_hammer-msg.sm | 83 ++ src/mem/protocol/MOESI_hammer.slicc | 5 + 4 files changed, 1509 insertions(+) create mode 100644 src/mem/protocol/MOESI_hammer-cache.sm create mode 100644 src/mem/protocol/MOESI_hammer-dir.sm create mode 100644 src/mem/protocol/MOESI_hammer-msg.sm create mode 100644 src/mem/protocol/MOESI_hammer.slicc diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm new file mode 100644 index 0000000000..d244a9b93d --- /dev/null +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -0,0 +1,1104 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +machine(L1Cache, "AMD Hammer-like protocol") { + + // STATES + enumeration(State, desc="Cache states", default="L1Cache_State_I") { + // Base states + I, desc="Idle"; + S, desc="Shared"; + O, desc="Owned"; + M, desc="Modified (dirty)"; + MM, desc="Modified (dirty and locally modified)"; + + // Transient States + IM, "IM", desc="Issued GetX"; + SM, "SM", desc="Issued GetX, we still have an old copy of the line"; + OM, "OM", desc="Issued GetX, received data"; + ISM, "ISM", desc="Issued GetX, received data, waiting for all acks"; + M_W, "M^W", desc="Issued GetS, received exclusive data"; + MM_W, "MM^W", desc="Issued GetX, received exclusive data"; + IS, "IS", desc="Issued GetS"; + SS, "SS", desc="Issued GetS, received data, waiting for all acks"; + OI, "OI", desc="Issued PutO, waiting for ack"; + MI, "MI", desc="Issued PutX, waiting for ack"; + II, "II", desc="Issued PutX/O, saw Other_GETS or Other_GETX, waiting for ack"; + } + + // EVENTS + enumeration(Event, desc="Cache events") { + Load, desc="Load request from the processor"; + Ifetch, desc="I-fetch request from the processor"; + Store, desc="Store request from the processor"; + L2_Replacement, desc="L2 Replacement"; + L1_to_L2, desc="L1 to L2 transfer"; + L2_to_L1D, desc="L2 to L1-Data transfer"; + L2_to_L1I, desc="L2 to L1-Instruction transfer"; + + // Requests + Other_GETX, desc="A GetX from another processor"; + Other_GETS, desc="A GetS from another processor"; + + // Responses + Ack, desc="Received an ack message"; + Shared_Ack, desc="Received an ack message, responder has a shared copy"; + Data, desc="Received a data message"; + Shared_Data, desc="Received a data message, responder has a shared copy"; + Exclusive_Data, desc="Received a data message, responder had an exclusive copy, they gave it to us"; + + Writeback_Ack, desc="Writeback O.K. from directory"; + Writeback_Nack, desc="Writeback not O.K. from directory"; + + // Triggers + All_acks, desc="Received all required data and message acks"; + All_acks_no_sharers, desc="Received all acks and no other processor has a shared copy"; + } + + // TYPES + + // CacheEntry + structure(Entry, desc="...") { + Address Address, desc="Address of this block, required by CacheMemory"; + Time LastRef, desc="Last time this block was referenced, required by CacheMemory"; + AccessPermission Permission, desc="Access permission for this block, required by CacheMemory"; + DataBlock DataBlk, desc="data for the block, required by CacheMemory"; + State CacheState, desc="cache state"; + bool Dirty, desc="Is the data dirty (different than memory)?"; + } + + // TBE fields + structure(TBE, desc="...") { + State TBEState, desc="Transient state"; + DataBlock DataBlk, desc="data for the block, required for concurrent writebacks"; + bool Dirty, desc="Is the data dirty (different than memory)?"; + int NumPendingMsgs, desc="Number of acks/data messages that this processor is waiting for"; + bool Sharers, desc="On a GetS, did we find any other sharers in the system"; + } + + external_type(NewCacheMemory) { + bool cacheAvail(Address); + Address cacheProbe(Address); + void allocate(Address); + void deallocate(Address); + Entry lookup(Address); + void changePermission(Address, AccessPermission); + bool isTagPresent(Address); + } + + external_type(NewTBETable) { + TBE lookup(Address); + void allocate(Address); + void deallocate(Address); + bool isPresent(Address); + } + + NewTBETable TBEs, template_hack=""; + NewCacheMemory L1IcacheMemory, template_hack="", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,"L1I"'; + NewCacheMemory L1DcacheMemory, template_hack="", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,"L1D"'; + NewCacheMemory L2cacheMemory, template_hack="", constructor_hack='L2_CACHE_NUM_SETS_BITS,L2_CACHE_ASSOC,"L2"'; + + Entry getCacheEntry(Address addr), return_by_ref="yes" { + if (L2cacheMemory.isTagPresent(addr)) { + return L2cacheMemory[addr]; + } else if (L1DcacheMemory.isTagPresent(addr)) { + return L1DcacheMemory[addr]; + } else { + return L1IcacheMemory[addr]; + } + } + + void changePermission(Address addr, AccessPermission permission) { + if (L2cacheMemory.isTagPresent(addr)) { + return L2cacheMemory.changePermission(addr, permission); + } else if (L1DcacheMemory.isTagPresent(addr)) { + return L1DcacheMemory.changePermission(addr, permission); + } else { + return L1IcacheMemory.changePermission(addr, permission); + } + } + + bool isCacheTagPresent(Address addr) { + return (L2cacheMemory.isTagPresent(addr) || L1DcacheMemory.isTagPresent(addr) || L1IcacheMemory.isTagPresent(addr)); + } + + State getState(Address addr) { + assert((L1DcacheMemory.isTagPresent(addr) && L1IcacheMemory.isTagPresent(addr)) == false); + assert((L1IcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false); + assert((L1DcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false); + + if(TBEs.isPresent(addr)) { + return TBEs[addr].TBEState; + } else if (isCacheTagPresent(addr)) { + return getCacheEntry(addr).CacheState; + } + return State:I; + } + + void setState(Address addr, State state) { + assert((L1DcacheMemory.isTagPresent(addr) && L1IcacheMemory.isTagPresent(addr)) == false); + assert((L1IcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false); + assert((L1DcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false); + + if (TBEs.isPresent(addr)) { + TBEs[addr].TBEState := state; + } + + if (isCacheTagPresent(addr)) { + getCacheEntry(addr).CacheState := state; + + // Set permission + if ((state == State:MM) || + (state == State:MM_W)) { + changePermission(addr, AccessPermission:Read_Write); + } else if (state == State:S || + state == State:O || + state == State:M || + state == State:M_W || + state == State:SM || + state == State:ISM || + state == State:OM || + state == State:SS) { + changePermission(addr, AccessPermission:Read_Only); + } else { + changePermission(addr, AccessPermission:Invalid); + } + } + } + + Event mandatory_request_type_to_event(CacheRequestType type) { + if (type == CacheRequestType:LD) { + return Event:Load; + } else if (type == CacheRequestType:IFETCH) { + return Event:Ifetch; + } else if ((type == CacheRequestType:ST) || (type == CacheRequestType:ATOMIC)) { + return Event:Store; + } else { + error("Invalid CacheRequestType"); + } + } + + MessageBuffer triggerQueue, ordered="true"; + + // ** OUT_PORTS ** + + out_port(requestNetwork_out, RequestMsg, requestFromCache); + out_port(responseNetwork_out, ResponseMsg, responseFromCache); + out_port(unblockNetwork_out, ResponseMsg, unblockFromCache); + out_port(triggerQueue_out, TriggerMsg, triggerQueue); + + // ** IN_PORTS ** + + // Trigger Queue + in_port(triggerQueue_in, TriggerMsg, triggerQueue) { + if (triggerQueue_in.isReady()) { + peek(triggerQueue_in, TriggerMsg) { + if (in_msg.Type == TriggerType:ALL_ACKS) { + trigger(Event:All_acks, in_msg.Address); + } else if (in_msg.Type == TriggerType:ALL_ACKS_NO_SHARERS) { + trigger(Event:All_acks_no_sharers, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + + // Nothing from the request network + + // Forward Network + in_port(forwardToCache_in, RequestMsg, forwardToCache) { + if (forwardToCache_in.isReady()) { + peek(forwardToCache_in, RequestMsg) { + if (in_msg.Type == CoherenceRequestType:GETX) { + trigger(Event:Other_GETX, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:GETS) { + trigger(Event:Other_GETS, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:WB_ACK) { + trigger(Event:Writeback_Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:WB_NACK) { + trigger(Event:Writeback_Nack, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + + // Response Network + in_port(responseToCache_in, ResponseMsg, responseToCache) { + if (responseToCache_in.isReady()) { + peek(responseToCache_in, ResponseMsg) { + if (in_msg.Type == CoherenceResponseType:ACK) { + trigger(Event:Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK_SHARED) { + trigger(Event:Shared_Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA) { + trigger(Event:Data, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) { + trigger(Event:Shared_Data, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { + trigger(Event:Exclusive_Data, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + + // Nothing from the unblock network + + // Mandatory Queue + in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...") { + if (mandatoryQueue_in.isReady()) { + peek(mandatoryQueue_in, CacheMsg) { + + // Check for data access to blocks in I-cache and ifetchs to blocks in D-cache + + if (in_msg.Type == CacheRequestType:IFETCH) { + // ** INSTRUCTION ACCESS *** + + // Check to see if it is in the OTHER L1 + if (L1DcacheMemory.isTagPresent(in_msg.Address)) { + // The block is in the wrong L1, try to write it to the L2 + if (L2cacheMemory.cacheAvail(in_msg.Address)) { + trigger(Event:L1_to_L2, in_msg.Address); + } else { + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.Address)); + } + } + + if (L1IcacheMemory.isTagPresent(in_msg.Address)) { + // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + } else { + if (L1IcacheMemory.cacheAvail(in_msg.Address)) { + // L1 does't have the line, but we have space for it in the L1 + if (L2cacheMemory.isTagPresent(in_msg.Address)) { + // L2 has it (maybe not with the right permissions) + trigger(Event:L2_to_L1I, in_msg.Address); + } else { + // We have room, the L2 doesn't have it, so the L1 fetches the line + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + } + } else { + // No room in the L1, so we need to make room + if (L2cacheMemory.cacheAvail(L1IcacheMemory.cacheProbe(in_msg.Address))) { + // The L2 has room, so we move the line from the L1 to the L2 + trigger(Event:L1_to_L2, L1IcacheMemory.cacheProbe(in_msg.Address)); + } else { + // The L2 does not have room, so we replace a line from the L2 + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1IcacheMemory.cacheProbe(in_msg.Address))); + } + } + } + } else { + // *** DATA ACCESS *** + + // Check to see if it is in the OTHER L1 + if (L1IcacheMemory.isTagPresent(in_msg.Address)) { + // The block is in the wrong L1, try to write it to the L2 + if (L2cacheMemory.cacheAvail(in_msg.Address)) { + trigger(Event:L1_to_L2, in_msg.Address); + } else { + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.Address)); + } + } + + if (L1DcacheMemory.isTagPresent(in_msg.Address)) { + // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + } else { + if (L1DcacheMemory.cacheAvail(in_msg.Address)) { + // L1 does't have the line, but we have space for it in the L1 + if (L2cacheMemory.isTagPresent(in_msg.Address)) { + // L2 has it (maybe not with the right permissions) + trigger(Event:L2_to_L1D, in_msg.Address); + } else { + // We have room, the L2 doesn't have it, so the L1 fetches the line + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + } + } else { + // No room in the L1, so we need to make room + if (L2cacheMemory.cacheAvail(L1DcacheMemory.cacheProbe(in_msg.Address))) { + // The L2 has room, so we move the line from the L1 to the L2 + trigger(Event:L1_to_L2, L1DcacheMemory.cacheProbe(in_msg.Address)); + } else { + // The L2 does not have room, so we replace a line from the L2 + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1DcacheMemory.cacheProbe(in_msg.Address))); + } + } + } + } + } + } + } + + // ACTIONS + + action(a_issueGETS, "a", desc="Issue GETS") { + enqueue(requestNetwork_out, RequestMsg, latency="ISSUE_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETS; + out_msg.Requestor := id; + out_msg.Destination.add(map_address_to_node(address)); + out_msg.MessageSize := MessageSizeType:Request_Control; + TBEs[address].NumPendingMsgs := numberOfNodes(); // One from each other processor (n-1) plus the memory (+1) + } + } + + action(b_issueGETX, "b", desc="Issue GETX") { + enqueue(requestNetwork_out, RequestMsg, latency="ISSUE_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETX; + out_msg.Requestor := id; + out_msg.Destination.add(map_address_to_node(address)); + out_msg.MessageSize := MessageSizeType:Request_Control; + TBEs[address].NumPendingMsgs := numberOfNodes(); // One from each other processor (n-1) plus the memory (+1) + } + } + + action(c_sendExclusiveData, "c", desc="Send exclusive data from cache to requestor") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; + out_msg.Sender := id; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := getCacheEntry(address).DataBlk; + out_msg.Dirty := getCacheEntry(address).Dirty; + out_msg.Acks := 2; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(d_issuePUT, "d", desc="Issue PUT") { + enqueue(requestNetwork_out, RequestMsg, latency="CACHE_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:PUT; + out_msg.Requestor := id; + out_msg.Destination.add(map_address_to_node(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + + action(e_sendData, "e", desc="Send data from cache to requestor") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA; + out_msg.Sender := id; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := getCacheEntry(address).DataBlk; + out_msg.Dirty := getCacheEntry(address).Dirty; + out_msg.Acks := 2; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(ee_sendDataShared, "\e", desc="Send data from cache to requestor, keep a shared copy") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA_SHARED; + out_msg.Sender := id; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := getCacheEntry(address).DataBlk; + out_msg.Dirty := getCacheEntry(address).Dirty; + out_msg.Acks := 2; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(f_sendAck, "f", desc="Send ack from cache to requestor") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:ACK; + out_msg.Sender := id; + out_msg.Destination.add(in_msg.Requestor); + out_msg.Acks := 1; + out_msg.MessageSize := MessageSizeType:Response_Control; + } + } + } + + action(ff_sendAckShared, "\f", desc="Send shared ack from cache to requestor") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:ACK_SHARED; + out_msg.Sender := id; + out_msg.Destination.add(in_msg.Requestor); + out_msg.Acks := 1; + out_msg.MessageSize := MessageSizeType:Response_Control; + } + } + } + + action(g_sendUnblock, "g", desc="Send unblock to memory") { + enqueue(unblockNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:UNBLOCK; + out_msg.Sender := id; + out_msg.Destination.add(map_address_to_node(address)); + out_msg.MessageSize := MessageSizeType:Unblock_Control; + } + } + + action(h_load_hit, "h", desc="Notify sequencer the load completed.") { + DEBUG_EXPR(getCacheEntry(address).DataBlk); + sequencer.readCallback(address, getCacheEntry(address).DataBlk); + } + + action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") { + DEBUG_EXPR(getCacheEntry(address).DataBlk); + sequencer.writeCallback(address, getCacheEntry(address).DataBlk); + getCacheEntry(address).Dirty := true; + } + + action(i_allocateTBE, "i", desc="Allocate TBE") { + check_allocate(TBEs); + TBEs.allocate(address); + TBEs[address].DataBlk := getCacheEntry(address).DataBlk; // Data only used for writebacks + TBEs[address].Dirty := getCacheEntry(address).Dirty; + TBEs[address].Sharers := false; + } + + action(j_popTriggerQueue, "j", desc="Pop trigger queue.") { + triggerQueue_in.dequeue(); + } + + action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") { + mandatoryQueue_in.dequeue(); + } + + action(l_popForwardQueue, "l", desc="Pop forwareded request queue.") { + forwardToCache_in.dequeue(); + } + + action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") { + peek(responseToCache_in, ResponseMsg) { + assert(in_msg.Acks > 0); + DEBUG_EXPR(TBEs[address].NumPendingMsgs); + TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - in_msg.Acks; + DEBUG_EXPR(TBEs[address].NumPendingMsgs); + } + } + + action(n_popResponseQueue, "n", desc="Pop response queue") { + responseToCache_in.dequeue(); + } + + action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") { + if (TBEs[address].NumPendingMsgs == 0) { + enqueue(triggerQueue_out, TriggerMsg) { + out_msg.Address := address; + if (TBEs[address].Sharers) { + out_msg.Type := TriggerType:ALL_ACKS; + } else { + out_msg.Type := TriggerType:ALL_ACKS_NO_SHARERS; + } + } + } + } + + action(p_decrementNumberOfMessagesByOne, "p", desc="Decrement the number of messages for which we're waiting by one") { + TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - 1; + } + + action(pp_incrementNumberOfMessagesByOne, "\p", desc="Increment the number of messages for which we're waiting by one") { + TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs + 1; + } + + action(q_sendDataFromTBEToCache, "q", desc="Send data from TBE to cache") { + peek(forwardToCache_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA; + out_msg.Sender := id; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.Dirty := TBEs[address].Dirty; + out_msg.Acks := 2; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(qq_sendDataFromTBEToMemory, "\q", desc="Send data from TBE to memory") { + enqueue(unblockNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + out_msg.Address := address; + out_msg.Sender := id; + out_msg.Destination.add(map_address_to_node(address)); + out_msg.Dirty := TBEs[address].Dirty; + if (TBEs[address].Dirty) { + out_msg.Type := CoherenceResponseType:WB_DIRTY; + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + } else { + out_msg.Type := CoherenceResponseType:WB_CLEAN; + // NOTE: in a real system this would not send data. We send + // data here only so we can check it at the memory + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(r_setSharerBit, "r", desc="We saw other sharers") { + TBEs[address].Sharers := true; + } + + action(s_deallocateTBE, "s", desc="Deallocate TBE") { + TBEs.deallocate(address); + } + + action(t_sendExclusiveDataFromTBEToMemory, "t", desc="Send exclusive data from TBE to memory") { + enqueue(unblockNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + out_msg.Address := address; + out_msg.Sender := id; + out_msg.Destination.add(map_address_to_node(address)); + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.Dirty := TBEs[address].Dirty; + if (TBEs[address].Dirty) { + out_msg.Type := CoherenceResponseType:WB_EXCLUSIVE_DIRTY; + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.MessageSize := MessageSizeType:Writeback_Data; + } else { + out_msg.Type := CoherenceResponseType:WB_EXCLUSIVE_CLEAN; + // NOTE: in a real system this would not send data. We send + // data here only so we can check it at the memory + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(u_writeDataToCache, "u", desc="Write data to cache") { + peek(responseToCache_in, ResponseMsg) { + getCacheEntry(address).DataBlk := in_msg.DataBlk; + getCacheEntry(address).Dirty := in_msg.Dirty; + } + } + + action(v_writeDataToCacheVerify, "v", desc="Write data to cache, assert it was same as before") { + peek(responseToCache_in, ResponseMsg) { + assert(getCacheEntry(address).DataBlk == in_msg.DataBlk); + getCacheEntry(address).DataBlk := in_msg.DataBlk; + getCacheEntry(address).Dirty := in_msg.Dirty; + } + } + + action(gg_deallocateL1CacheBlock, "\g", desc="Deallocate cache block. Sets the cache to invalid, allowing a replacement in parallel with a fetch.") { + if (L1DcacheMemory.isTagPresent(address)) { + L1DcacheMemory.deallocate(address); + } else { + L1IcacheMemory.deallocate(address); + } + } + + action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") { + if (L1DcacheMemory.isTagPresent(address) == false) { + L1DcacheMemory.allocate(address); + } + } + + action(jj_allocateL1ICacheBlock, "\j", desc="Set L1 I-cache tag equal to tag of block B.") { + if (L1IcacheMemory.isTagPresent(address) == false) { + L1IcacheMemory.allocate(address); + } + } + + action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") { + L2cacheMemory.allocate(address); + } + + action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") { + L2cacheMemory.deallocate(address); + } + + action(ss_copyFromL1toL2, "\s", desc="Copy data block from L1 (I or D) to L2") { + if (L1DcacheMemory.isTagPresent(address)) { + L2cacheMemory[address] := L1DcacheMemory[address]; + } else { + L2cacheMemory[address] := L1IcacheMemory[address]; + } + } + + action(tt_copyFromL2toL1, "\t", desc="Copy data block from L2 to L1 (I or D)") { + if (L1DcacheMemory.isTagPresent(address)) { + L1DcacheMemory[address] := L2cacheMemory[address]; + } else { + L1IcacheMemory[address] := L2cacheMemory[address]; + } + } + + action(uu_profileMiss, "\u", desc="Profile the demand miss") { + peek(mandatoryQueue_in, CacheMsg) { + profile_miss(in_msg, id); + } + } + + action(zz_recycleMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") { + mandatoryQueue_in.recycle(); + } + + //***************************************************** + // TRANSITIONS + //***************************************************** + + // Transitions for Load/Store/L2_Replacement from transient states + transition({IM, SM, ISM, OM, IS, SS, OI, MI, II}, {Store, L2_Replacement}) { + zz_recycleMandatoryQueue; + } + + transition({M_W, MM_W}, {L2_Replacement}) { + zz_recycleMandatoryQueue; + } + + transition({IM, IS, OI, MI, II}, {Load, Ifetch}) { + zz_recycleMandatoryQueue; + } + + transition({IM, SM, ISM, OM, IS, SS, MM_W, M_W, OI, MI, II}, L1_to_L2) { + zz_recycleMandatoryQueue; + } + + // Transitions moving data between the L1 and L2 caches + transition({I, S, O, M, MM}, L1_to_L2) { + vv_allocateL2CacheBlock; + ss_copyFromL1toL2; // Not really needed for state I + gg_deallocateL1CacheBlock; + } + + transition({I, S, O, M, MM}, L2_to_L1D) { + ii_allocateL1DCacheBlock; + tt_copyFromL2toL1; // Not really needed for state I + rr_deallocateL2CacheBlock; + } + + transition({I, S, O, M, MM}, L2_to_L1I) { + jj_allocateL1ICacheBlock; + tt_copyFromL2toL1; // Not really needed for state I + rr_deallocateL2CacheBlock; + } + + // Transitions from Idle + transition(I, Load, IS) { + ii_allocateL1DCacheBlock; + i_allocateTBE; + a_issueGETS; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(I, Ifetch, IS) { + jj_allocateL1ICacheBlock; + i_allocateTBE; + a_issueGETS; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(I, Store, IM) { + ii_allocateL1DCacheBlock; + i_allocateTBE; + b_issueGETX; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(I, L2_Replacement) { + rr_deallocateL2CacheBlock; + } + + transition(I, {Other_GETX, Other_GETS}) { + f_sendAck; + l_popForwardQueue; + } + + // Transitions from Shared + transition({S, SM, ISM}, {Load, Ifetch}) { + h_load_hit; + k_popMandatoryQueue; + } + + transition(S, Store, SM) { + i_allocateTBE; + b_issueGETX; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(S, L2_Replacement, I) { + rr_deallocateL2CacheBlock; + } + + transition(S, Other_GETX, I) { + f_sendAck; + l_popForwardQueue; + } + + transition(S, Other_GETS) { + ff_sendAckShared; + l_popForwardQueue; + } + + // Transitions from Owned + transition({O, OM, SS, MM_W, M_W}, {Load, Ifetch}) { + h_load_hit; + k_popMandatoryQueue; + } + + transition(O, Store, OM) { + i_allocateTBE; + b_issueGETX; + p_decrementNumberOfMessagesByOne; + uu_profileMiss; + k_popMandatoryQueue; + } + + transition(O, L2_Replacement, OI) { + i_allocateTBE; + d_issuePUT; + rr_deallocateL2CacheBlock; + } + + transition(O, Other_GETX, I) { + e_sendData; + l_popForwardQueue; + } + + transition(O, Other_GETS) { + ee_sendDataShared; + l_popForwardQueue; + } + + // Transitions from Modified + transition(MM, {Load, Ifetch}) { + h_load_hit; + k_popMandatoryQueue; + } + + transition(MM, Store) { + hh_store_hit; + k_popMandatoryQueue; + } + + transition(MM, L2_Replacement, MI) { + i_allocateTBE; + d_issuePUT; + rr_deallocateL2CacheBlock; + } + + transition(MM, Other_GETX, I) { + c_sendExclusiveData; + l_popForwardQueue; + } + + transition(MM, Other_GETS, I) { + c_sendExclusiveData; + l_popForwardQueue; + } + + // Transitions from Dirty Exclusive + transition(M, {Load, Ifetch}) { + h_load_hit; + k_popMandatoryQueue; + } + + transition(M, Store, MM) { + hh_store_hit; + k_popMandatoryQueue; + } + + transition(M, L2_Replacement, MI) { + i_allocateTBE; + d_issuePUT; + rr_deallocateL2CacheBlock; + } + + transition(M, Other_GETX, I) { + c_sendExclusiveData; + l_popForwardQueue; + } + + transition(M, Other_GETS, O) { + ee_sendDataShared; + l_popForwardQueue; + } + + // Transitions from IM + + transition(IM, {Other_GETX, Other_GETS}) { + f_sendAck; + l_popForwardQueue; + } + + transition(IM, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(IM, Data, ISM) { + u_writeDataToCache; + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(IM, Exclusive_Data, MM_W) { + u_writeDataToCache; + m_decrementNumberOfMessages; + o_checkForCompletion; + hh_store_hit; + n_popResponseQueue; + } + + // Transitions from SM + transition(SM, Other_GETS) { + ff_sendAckShared; + l_popForwardQueue; + } + + transition(SM, Other_GETX, IM) { + f_sendAck; + l_popForwardQueue; + } + + transition(SM, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(SM, Data, ISM) { + v_writeDataToCacheVerify; + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + // Transitions from ISM + transition(ISM, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(ISM, All_acks_no_sharers, MM) { + hh_store_hit; + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from OM + + transition(OM, Other_GETX, IM) { + e_sendData; + pp_incrementNumberOfMessagesByOne; + l_popForwardQueue; + } + + transition(OM, Other_GETS) { + ee_sendDataShared; + l_popForwardQueue; + } + + transition(OM, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(OM, {All_acks, All_acks_no_sharers}, MM) { + hh_store_hit; + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from IS + + transition(IS, {Other_GETX, Other_GETS}) { + f_sendAck; + l_popForwardQueue; + } + + transition(IS, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(IS, Shared_Ack) { + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(IS, Data, SS) { + u_writeDataToCache; + m_decrementNumberOfMessages; + o_checkForCompletion; + h_load_hit; + n_popResponseQueue; + } + + transition(IS, Exclusive_Data, M_W) { + u_writeDataToCache; + m_decrementNumberOfMessages; + o_checkForCompletion; + h_load_hit; + n_popResponseQueue; + } + + transition(IS, Shared_Data, SS) { + u_writeDataToCache; + r_setSharerBit; + m_decrementNumberOfMessages; + o_checkForCompletion; + h_load_hit; + n_popResponseQueue; + } + + // Transitions from SS + + transition(SS, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(SS, Shared_Ack) { + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(SS, All_acks, S) { + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + transition(SS, All_acks_no_sharers, S) { + // Note: The directory might still be the owner, so that is why we go to S + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from MM_W + + transition(MM_W, Store) { + hh_store_hit; + k_popMandatoryQueue; + } + + transition(MM_W, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(MM_W, All_acks_no_sharers, MM) { + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from M_W + + transition(M_W, Store, MM_W) { + hh_store_hit; + k_popMandatoryQueue; + } + + transition(M_W, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(M_W, All_acks_no_sharers, M) { + g_sendUnblock; + s_deallocateTBE; + j_popTriggerQueue; + } + + // Transitions from OI/MI + + transition({OI, MI}, Other_GETX, II) { + q_sendDataFromTBEToCache; + l_popForwardQueue; + } + + transition({OI, MI}, Other_GETS, OI) { + q_sendDataFromTBEToCache; + l_popForwardQueue; + } + + transition(MI, Writeback_Ack, I) { + t_sendExclusiveDataFromTBEToMemory; + s_deallocateTBE; + l_popForwardQueue; + } + + transition(OI, Writeback_Ack, I) { + qq_sendDataFromTBEToMemory; + s_deallocateTBE; + l_popForwardQueue; + } + + // Transitions from II + transition(II, {Other_GETS, Other_GETX}, II) { + f_sendAck; + l_popForwardQueue; + } + + transition(II, Writeback_Ack, I) { + g_sendUnblock; + s_deallocateTBE; + l_popForwardQueue; + } + + transition(II, Writeback_Nack, I) { + s_deallocateTBE; + l_popForwardQueue; + } +} + diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm new file mode 100644 index 0000000000..836fa97874 --- /dev/null +++ b/src/mem/protocol/MOESI_hammer-dir.sm @@ -0,0 +1,317 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +machine(Directory, "AMD Hammer-like protocol") { + + // STATES + enumeration(State, desc="Directory states", default="Directory_State_E") { + // Base states + NO, desc="Not Owner"; + O, desc="Owner"; + E, desc="Exclusive Owner (we can provide the data in exclusive)"; + NO_B, "NO^B", desc="Not Owner, Blocked"; + O_B, "O^B", desc="Owner, Blocked"; + WB, desc="Blocked on a writeback"; + } + + // Events + enumeration(Event, desc="Directory events") { + GETX, desc="A GETX arrives"; + GETS, desc="A GETS arrives"; + PUT, desc="A PUT arrives"; + Unblock, desc="An unblock message arrives"; + Writeback_Clean, desc="The final part of a PutX (no data)"; + Writeback_Dirty, desc="The final part of a PutX (data)"; + Writeback_Exclusive_Clean, desc="The final part of a PutX (no data, exclusive)"; + Writeback_Exclusive_Dirty, desc="The final part of a PutX (data, exclusive)"; + } + + // TYPES + + // DirectoryEntry + structure(Entry, desc="...") { + State DirectoryState, desc="Directory state"; + DataBlock DataBlk, desc="data for the block"; + } + + external_type(DirectoryMemory) { + Entry lookup(Address); + bool isPresent(Address); + } + + // ** OBJECTS ** + + DirectoryMemory directory; + + State getState(Address addr) { + return directory[addr].DirectoryState; + } + + void setState(Address addr, State state) { + directory[addr].DirectoryState := state; + } + + // ** OUT_PORTS ** + out_port(forwardNetwork_out, RequestMsg, forwardFromDir); + out_port(responseNetwork_out, ResponseMsg, responseFromDir); + out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests + + // ** IN_PORTS ** + + in_port(unblockNetwork_in, ResponseMsg, unblockToDir) { + if (unblockNetwork_in.isReady()) { + peek(unblockNetwork_in, ResponseMsg) { + if (in_msg.Type == CoherenceResponseType:UNBLOCK) { + trigger(Event:Unblock, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:WB_CLEAN) { + trigger(Event:Writeback_Clean, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:WB_DIRTY) { + trigger(Event:Writeback_Dirty, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:WB_EXCLUSIVE_CLEAN) { + trigger(Event:Writeback_Exclusive_Clean, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:WB_EXCLUSIVE_DIRTY) { + trigger(Event:Writeback_Exclusive_Dirty, in_msg.Address); + } else { + error("Invalid message"); + } + } + } + } + + in_port(requestQueue_in, RequestMsg, requestToDir) { + if (requestQueue_in.isReady()) { + peek(requestQueue_in, RequestMsg) { + if (in_msg.Type == CoherenceRequestType:GETS) { + trigger(Event:GETS, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:GETX) { + trigger(Event:GETX, in_msg.Address); + } else if (in_msg.Type == CoherenceRequestType:PUT) { + trigger(Event:PUT, in_msg.Address); + } else { + error("Invalid message"); + } + } + } + } + + // Actions + + action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") { + peek(requestQueue_in, RequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:WB_ACK; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.add(in_msg.Requestor); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") { + peek(requestQueue_in, RequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:WB_NACK; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.add(in_msg.Requestor); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(d_sendData, "d", desc="Send data to requestor") { + peek(requestQueue_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA; + out_msg.Sender := id; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := directory[in_msg.Address].DataBlk; + out_msg.Dirty := false; // By definition, the block is now clean + out_msg.Acks := 1; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(dd_sendExclusiveData, "\d", desc="Send exclusive data to requestor") { + peek(requestQueue_in, RequestMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; + out_msg.Sender := id; + out_msg.Destination.add(in_msg.Requestor); + out_msg.DataBlk := directory[in_msg.Address].DataBlk; + out_msg.Dirty := false; // By definition, the block is now clean + out_msg.Acks := 1; + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(f_forwardRequest, "f", desc="Forward requests") { + if (numberOfNodes() > 1) { + peek(requestQueue_in, RequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") { + out_msg.Address := address; + out_msg.Type := in_msg.Type; + out_msg.Requestor := in_msg.Requestor; + out_msg.Destination.broadcast(); // Send to everyone, but... + out_msg.Destination.remove(in_msg.Requestor); // Don't include the original requestor + out_msg.MessageSize := MessageSizeType:Forwarded_Control; + } + } + } + } + + action(i_popIncomingRequestQueue, "i", desc="Pop incoming request queue") { + requestQueue_in.dequeue(); + } + + action(j_popIncomingUnblockQueue, "j", desc="Pop incoming unblock queue") { + unblockNetwork_in.dequeue(); + } + + action(l_writeDataToMemory, "l", desc="Write PUTX/PUTO data to memory") { + peek(unblockNetwork_in, ResponseMsg) { + assert(in_msg.Dirty); + assert(in_msg.MessageSize == MessageSizeType:Writeback_Data); + directory[in_msg.Address].DataBlk := in_msg.DataBlk; + DEBUG_EXPR(in_msg.Address); + DEBUG_EXPR(in_msg.DataBlk); + } + } + + action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") { + peek(unblockNetwork_in, ResponseMsg) { + assert(in_msg.Dirty == false); + assert(in_msg.MessageSize == MessageSizeType:Writeback_Control); + + // NOTE: The following check would not be valid in a real + // implementation. We include the data in the "dataless" + // message so we can assert the clean data matches the datablock + // in memory + assert(directory[in_msg.Address].DataBlk == in_msg.DataBlk); + } + } + + // action(z_stall, "z", desc="Cannot be handled right now.") { + // Special name recognized as do nothing case + // } + + action(zz_recycleRequest, "\z", desc="Recycle the request queue") { + requestQueue_in.recycle(); + } + + // TRANSITIONS + + transition(E, GETX, NO_B) { + dd_sendExclusiveData; + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(E, GETS, NO_B) { + dd_sendExclusiveData; + f_forwardRequest; + i_popIncomingRequestQueue; + } + + // + transition(O, GETX, NO_B) { + d_sendData; + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(O, GETS, O_B) { + d_sendData; + f_forwardRequest; + i_popIncomingRequestQueue; + } + + // + transition(NO, GETX, NO_B) { + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(NO, GETS, NO_B) { + f_forwardRequest; + i_popIncomingRequestQueue; + } + + transition(NO, PUT, WB) { + a_sendWriteBackAck; + i_popIncomingRequestQueue; + } + + transition({O, E}, PUT) { + b_sendWriteBackNack; + i_popIncomingRequestQueue; + } + + // Blocked states + transition({NO_B, O_B, WB}, {GETS, GETX, PUT}) { + zz_recycleRequest; + } + + transition(NO_B, Unblock, NO) { + j_popIncomingUnblockQueue; + } + + transition(O_B, Unblock, O) { + j_popIncomingUnblockQueue; + } + + // WB + transition(WB, Writeback_Dirty, O) { + l_writeDataToMemory; + j_popIncomingUnblockQueue; + } + + transition(WB, Writeback_Exclusive_Dirty, E) { + l_writeDataToMemory; + j_popIncomingUnblockQueue; + } + + transition(WB, Writeback_Clean, O) { + ll_checkIncomingWriteback; + j_popIncomingUnblockQueue; + } + + transition(WB, Writeback_Exclusive_Clean, E) { + ll_checkIncomingWriteback; + j_popIncomingUnblockQueue; + } + + transition(WB, Unblock, NO) { + j_popIncomingUnblockQueue; + } +} diff --git a/src/mem/protocol/MOESI_hammer-msg.sm b/src/mem/protocol/MOESI_hammer-msg.sm new file mode 100644 index 0000000000..43e00a2d1a --- /dev/null +++ b/src/mem/protocol/MOESI_hammer-msg.sm @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// CoherenceRequestType +enumeration(CoherenceRequestType, desc="...") { + GETX, desc="Get eXclusive"; + GETS, desc="Get Shared"; + PUT, desc="Put Ownership"; + WB_ACK, desc="Writeback ack"; + WB_NACK, desc="Writeback neg. ack"; +} + +// CoherenceResponseType +enumeration(CoherenceResponseType, desc="...") { + ACK, desc="ACKnowledgment, responder does not have a copy"; + ACK_SHARED, desc="ACKnowledgment, responder has a shared copy"; + DATA, desc="Data, responder does not have a copy"; + DATA_SHARED, desc="Data, responder has a shared copy"; + DATA_EXCLUSIVE, desc="Data, responder was exclusive, gave us a copy, and they went to invalid"; + WB_CLEAN, desc="Clean writeback"; + WB_DIRTY, desc="Dirty writeback"; + WB_EXCLUSIVE_CLEAN, desc="Clean writeback of exclusive data"; + WB_EXCLUSIVE_DIRTY, desc="Dirty writeback of exclusive data"; + UNBLOCK, desc="Unblock"; +} + +// TriggerType +enumeration(TriggerType, desc="...") { + ALL_ACKS, desc="See corresponding event"; + ALL_ACKS_NO_SHARERS, desc="See corresponding event"; +} + +// TriggerMsg +structure(TriggerMsg, desc="...", interface="Message") { + Address Address, desc="Physical address for this request"; + TriggerType Type, desc="Type of trigger"; +} + +// RequestMsg (and also forwarded requests) +structure(RequestMsg, desc="...", interface="NetworkMessage") { + Address Address, desc="Physical address for this request"; + CoherenceRequestType Type, desc="Type of request (GetS, GetX, PutX, etc)"; + NodeID Requestor, desc="Node who initiated the request"; + NetDest Destination, desc="Multicast destination mask"; + MessageSizeType MessageSize, desc="size category of the message"; +} + +// ResponseMsg (and also unblock requests) +structure(ResponseMsg, desc="...", interface="NetworkMessage") { + Address Address, desc="Physical address for this request"; + CoherenceResponseType Type, desc="Type of response (Ack, Data, etc)"; + NodeID Sender, desc="Node who sent the data"; + NetDest Destination, desc="Node to whom the data is sent"; + DataBlock DataBlk, desc="data for the cache line"; + bool Dirty, desc="Is the data dirty (different than memory)?"; + int Acks, desc="How many messages this counts as"; + MessageSizeType MessageSize, desc="size category of the message"; +} diff --git a/src/mem/protocol/MOESI_hammer.slicc b/src/mem/protocol/MOESI_hammer.slicc new file mode 100644 index 0000000000..8ff931e044 --- /dev/null +++ b/src/mem/protocol/MOESI_hammer.slicc @@ -0,0 +1,5 @@ +../protocols/MOESI_hammer-msg.sm +../protocols/hammer-ni.sm +../protocols/MOESI_hammer-cache.sm +../protocols/MOESI_hammer-dir.sm +../protocols/standard_1level-node.sm From 877be2009c0871effb3494b52ce5221d58a594d6 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 149/160] ruby: Changes necessary to get the hammer protocol to work in GEM5 --- src/mem/protocol/MOESI_hammer-cache.sm | 178 ++++++++++++++----------- src/mem/protocol/MOESI_hammer-dir.sm | 38 ++++-- src/mem/protocol/MOESI_hammer-msg.sm | 7 +- src/mem/protocol/MOESI_hammer.slicc | 9 +- src/mem/protocol/SConsopts | 1 + 5 files changed, 141 insertions(+), 92 deletions(-) diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index d244a9b93d..6fb5091afe 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -1,5 +1,6 @@ /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,9 +25,27 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * AMD's contributions to the MOESI hammer protocol do not constitute an + * endorsement of its similarity to any AMD products. + * + * Authors: Milo Martin + * Brad Beckmann */ -machine(L1Cache, "AMD Hammer-like protocol") { +machine(L1Cache, "AMD Hammer-like protocol") +: int cache_response_latency, + int issue_latency +{ + + // NETWORK BUFFERS + MessageBuffer requestFromCache, network="To", virtual_network="3", ordered="false"; + MessageBuffer responseFromCache, network="To", virtual_network="1", ordered="false"; + MessageBuffer unblockFromCache, network="To", virtual_network="0", ordered="false"; + + MessageBuffer forwardToCache, network="From", virtual_network="2", ordered="false"; + MessageBuffer responseToCache, network="From", virtual_network="1", ordered="false"; + // STATES enumeration(State, desc="Cache states", default="L1Cache_State_I") { @@ -82,14 +101,16 @@ machine(L1Cache, "AMD Hammer-like protocol") { // TYPES + // STRUCTURE DEFINITIONS + + MessageBuffer mandatoryQueue, ordered="false"; + Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])'; + // CacheEntry - structure(Entry, desc="...") { - Address Address, desc="Address of this block, required by CacheMemory"; - Time LastRef, desc="Last time this block was referenced, required by CacheMemory"; - AccessPermission Permission, desc="Access permission for this block, required by CacheMemory"; - DataBlock DataBlk, desc="data for the block, required by CacheMemory"; + structure(Entry, desc="...", interface="AbstractCacheEntry") { State CacheState, desc="cache state"; bool Dirty, desc="Is the data dirty (different than memory)?"; + DataBlock DataBlk, desc="data for the block"; } // TBE fields @@ -101,27 +122,28 @@ machine(L1Cache, "AMD Hammer-like protocol") { bool Sharers, desc="On a GetS, did we find any other sharers in the system"; } - external_type(NewCacheMemory) { + external_type(CacheMemory) { bool cacheAvail(Address); Address cacheProbe(Address); - void allocate(Address); + void allocate(Address, Entry); void deallocate(Address); Entry lookup(Address); void changePermission(Address, AccessPermission); bool isTagPresent(Address); + void profileMiss(CacheMsg); } - external_type(NewTBETable) { + external_type(TBETable) { TBE lookup(Address); void allocate(Address); void deallocate(Address); bool isPresent(Address); } - NewTBETable TBEs, template_hack=""; - NewCacheMemory L1IcacheMemory, template_hack="", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,"L1I"'; - NewCacheMemory L1DcacheMemory, template_hack="", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,"L1D"'; - NewCacheMemory L2cacheMemory, template_hack="", constructor_hack='L2_CACHE_NUM_SETS_BITS,L2_CACHE_ASSOC,"L2"'; + TBETable TBEs, template_hack=""; + CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])'; + CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])'; + CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["cache"])'; Entry getCacheEntry(Address addr), return_by_ref="yes" { if (L2cacheMemory.isTagPresent(addr)) { @@ -284,36 +306,36 @@ machine(L1Cache, "AMD Hammer-like protocol") { // ** INSTRUCTION ACCESS *** // Check to see if it is in the OTHER L1 - if (L1DcacheMemory.isTagPresent(in_msg.Address)) { + if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) { // The block is in the wrong L1, try to write it to the L2 - if (L2cacheMemory.cacheAvail(in_msg.Address)) { - trigger(Event:L1_to_L2, in_msg.Address); + if (L2cacheMemory.cacheAvail(in_msg.LineAddress)) { + trigger(Event:L1_to_L2, in_msg.LineAddress); } else { - trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.Address)); + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.LineAddress)); } } - if (L1IcacheMemory.isTagPresent(in_msg.Address)) { + if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) { // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { - if (L1IcacheMemory.cacheAvail(in_msg.Address)) { + if (L1IcacheMemory.cacheAvail(in_msg.LineAddress)) { // L1 does't have the line, but we have space for it in the L1 - if (L2cacheMemory.isTagPresent(in_msg.Address)) { + if (L2cacheMemory.isTagPresent(in_msg.LineAddress)) { // L2 has it (maybe not with the right permissions) - trigger(Event:L2_to_L1I, in_msg.Address); + trigger(Event:L2_to_L1I, in_msg.LineAddress); } else { // We have room, the L2 doesn't have it, so the L1 fetches the line - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } } else { // No room in the L1, so we need to make room - if (L2cacheMemory.cacheAvail(L1IcacheMemory.cacheProbe(in_msg.Address))) { + if (L2cacheMemory.cacheAvail(L1IcacheMemory.cacheProbe(in_msg.LineAddress))) { // The L2 has room, so we move the line from the L1 to the L2 - trigger(Event:L1_to_L2, L1IcacheMemory.cacheProbe(in_msg.Address)); + trigger(Event:L1_to_L2, L1IcacheMemory.cacheProbe(in_msg.LineAddress)); } else { // The L2 does not have room, so we replace a line from the L2 - trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1IcacheMemory.cacheProbe(in_msg.Address))); + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1IcacheMemory.cacheProbe(in_msg.LineAddress))); } } } @@ -321,36 +343,36 @@ machine(L1Cache, "AMD Hammer-like protocol") { // *** DATA ACCESS *** // Check to see if it is in the OTHER L1 - if (L1IcacheMemory.isTagPresent(in_msg.Address)) { + if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) { // The block is in the wrong L1, try to write it to the L2 - if (L2cacheMemory.cacheAvail(in_msg.Address)) { - trigger(Event:L1_to_L2, in_msg.Address); + if (L2cacheMemory.cacheAvail(in_msg.LineAddress)) { + trigger(Event:L1_to_L2, in_msg.LineAddress); } else { - trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.Address)); + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.LineAddress)); } } - if (L1DcacheMemory.isTagPresent(in_msg.Address)) { + if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) { // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { - if (L1DcacheMemory.cacheAvail(in_msg.Address)) { + if (L1DcacheMemory.cacheAvail(in_msg.LineAddress)) { // L1 does't have the line, but we have space for it in the L1 - if (L2cacheMemory.isTagPresent(in_msg.Address)) { + if (L2cacheMemory.isTagPresent(in_msg.LineAddress)) { // L2 has it (maybe not with the right permissions) - trigger(Event:L2_to_L1D, in_msg.Address); + trigger(Event:L2_to_L1D, in_msg.LineAddress); } else { // We have room, the L2 doesn't have it, so the L1 fetches the line - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } } else { // No room in the L1, so we need to make room - if (L2cacheMemory.cacheAvail(L1DcacheMemory.cacheProbe(in_msg.Address))) { + if (L2cacheMemory.cacheAvail(L1DcacheMemory.cacheProbe(in_msg.LineAddress))) { // The L2 has room, so we move the line from the L1 to the L2 - trigger(Event:L1_to_L2, L1DcacheMemory.cacheProbe(in_msg.Address)); + trigger(Event:L1_to_L2, L1DcacheMemory.cacheProbe(in_msg.LineAddress)); } else { // The L2 does not have room, so we replace a line from the L2 - trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1DcacheMemory.cacheProbe(in_msg.Address))); + trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1DcacheMemory.cacheProbe(in_msg.LineAddress))); } } } @@ -362,33 +384,33 @@ machine(L1Cache, "AMD Hammer-like protocol") { // ACTIONS action(a_issueGETS, "a", desc="Issue GETS") { - enqueue(requestNetwork_out, RequestMsg, latency="ISSUE_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETS; - out_msg.Requestor := id; - out_msg.Destination.add(map_address_to_node(address)); + out_msg.Requestor := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Request_Control; - TBEs[address].NumPendingMsgs := numberOfNodes(); // One from each other processor (n-1) plus the memory (+1) + TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches(); // One from each other cache (n-1) plus the memory (+1) } } action(b_issueGETX, "b", desc="Issue GETX") { - enqueue(requestNetwork_out, RequestMsg, latency="ISSUE_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETX; - out_msg.Requestor := id; - out_msg.Destination.add(map_address_to_node(address)); + out_msg.Requestor := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Request_Control; - TBEs[address].NumPendingMsgs := numberOfNodes(); // One from each other processor (n-1) plus the memory (+1) + TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches(); // One from each other cache (n-1) plus the memory (+1) } } action(c_sendExclusiveData, "c", desc="Send exclusive data from cache to requestor") { peek(forwardToCache_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; - out_msg.Sender := id; + out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.DataBlk := getCacheEntry(address).DataBlk; out_msg.Dirty := getCacheEntry(address).Dirty; @@ -399,21 +421,21 @@ machine(L1Cache, "AMD Hammer-like protocol") { } action(d_issuePUT, "d", desc="Issue PUT") { - enqueue(requestNetwork_out, RequestMsg, latency="CACHE_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:PUT; - out_msg.Requestor := id; - out_msg.Destination.add(map_address_to_node(address)); + out_msg.Requestor := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } action(e_sendData, "e", desc="Send data from cache to requestor") { peek(forwardToCache_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA; - out_msg.Sender := id; + out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.DataBlk := getCacheEntry(address).DataBlk; out_msg.Dirty := getCacheEntry(address).Dirty; @@ -425,10 +447,10 @@ machine(L1Cache, "AMD Hammer-like protocol") { action(ee_sendDataShared, "\e", desc="Send data from cache to requestor, keep a shared copy") { peek(forwardToCache_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; - out_msg.Sender := id; + out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.DataBlk := getCacheEntry(address).DataBlk; out_msg.Dirty := getCacheEntry(address).Dirty; @@ -440,10 +462,10 @@ machine(L1Cache, "AMD Hammer-like protocol") { action(f_sendAck, "f", desc="Send ack from cache to requestor") { peek(forwardToCache_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; - out_msg.Sender := id; + out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.Acks := 1; out_msg.MessageSize := MessageSizeType:Response_Control; @@ -453,10 +475,10 @@ machine(L1Cache, "AMD Hammer-like protocol") { action(ff_sendAckShared, "\f", desc="Send shared ack from cache to requestor") { peek(forwardToCache_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK_SHARED; - out_msg.Sender := id; + out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.Acks := 1; out_msg.MessageSize := MessageSizeType:Response_Control; @@ -465,11 +487,11 @@ machine(L1Cache, "AMD Hammer-like protocol") { } action(g_sendUnblock, "g", desc="Send unblock to memory") { - enqueue(unblockNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(unblockNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:UNBLOCK; - out_msg.Sender := id; - out_msg.Destination.add(map_address_to_node(address)); + out_msg.Sender := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Unblock_Control; } } @@ -541,10 +563,10 @@ machine(L1Cache, "AMD Hammer-like protocol") { action(q_sendDataFromTBEToCache, "q", desc="Send data from TBE to cache") { peek(forwardToCache_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA; - out_msg.Sender := id; + out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.DataBlk := TBEs[address].DataBlk; out_msg.Dirty := TBEs[address].Dirty; @@ -555,10 +577,10 @@ machine(L1Cache, "AMD Hammer-like protocol") { } action(qq_sendDataFromTBEToMemory, "\q", desc="Send data from TBE to memory") { - enqueue(unblockNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + enqueue(unblockNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; - out_msg.Sender := id; - out_msg.Destination.add(map_address_to_node(address)); + out_msg.Sender := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.Dirty := TBEs[address].Dirty; if (TBEs[address].Dirty) { out_msg.Type := CoherenceResponseType:WB_DIRTY; @@ -583,10 +605,10 @@ machine(L1Cache, "AMD Hammer-like protocol") { } action(t_sendExclusiveDataFromTBEToMemory, "t", desc="Send exclusive data from TBE to memory") { - enqueue(unblockNetwork_out, ResponseMsg, latency="CACHE_LATENCY") { + enqueue(unblockNetwork_out, ResponseMsg, latency=cache_response_latency) { out_msg.Address := address; - out_msg.Sender := id; - out_msg.Destination.add(map_address_to_node(address)); + out_msg.Sender := machineID; + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.DataBlk := TBEs[address].DataBlk; out_msg.Dirty := TBEs[address].Dirty; if (TBEs[address].Dirty) { @@ -628,18 +650,18 @@ machine(L1Cache, "AMD Hammer-like protocol") { action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") { if (L1DcacheMemory.isTagPresent(address) == false) { - L1DcacheMemory.allocate(address); + L1DcacheMemory.allocate(address, new Entry); } } action(jj_allocateL1ICacheBlock, "\j", desc="Set L1 I-cache tag equal to tag of block B.") { if (L1IcacheMemory.isTagPresent(address) == false) { - L1IcacheMemory.allocate(address); + L1IcacheMemory.allocate(address, new Entry); } } action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") { - L2cacheMemory.allocate(address); + L2cacheMemory.allocate(address, new Entry); } action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") { @@ -664,7 +686,13 @@ machine(L1Cache, "AMD Hammer-like protocol") { action(uu_profileMiss, "\u", desc="Profile the demand miss") { peek(mandatoryQueue_in, CacheMsg) { - profile_miss(in_msg, id); + if (L1IcacheMemory.isTagPresent(address)) { + L1IcacheMemory.profileMiss(in_msg); + } else if (L1DcacheMemory.isTagPresent(address)) { + L1DcacheMemory.profileMiss(in_msg); + } else { + L2cacheMemory.profileMiss(in_msg); + } } } diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm index 836fa97874..0f7c58acde 100644 --- a/src/mem/protocol/MOESI_hammer-dir.sm +++ b/src/mem/protocol/MOESI_hammer-dir.sm @@ -1,5 +1,6 @@ /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * Copyright (c) 2009 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,9 +25,26 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * AMD's contributions to the MOESI hammer protocol do not constitute an + * endorsement of its similarity to any AMD products. + * + * Authors: Milo Martin + * Brad Beckmann */ -machine(Directory, "AMD Hammer-like protocol") { +machine(Directory, "AMD Hammer-like protocol") +: int memory_controller_latency, + int memory_latency +{ + + MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false"; + MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false"; +// MessageBuffer dmaRequestFromDir, network="To", virtual_network="4", ordered="true"; + + MessageBuffer requestToDir, network="From", virtual_network="3", ordered="false"; + MessageBuffer unblockToDir, network="From", virtual_network="0", ordered="false"; +// MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true"; // STATES enumeration(State, desc="Directory states", default="Directory_State_E") { @@ -66,7 +84,7 @@ machine(Directory, "AMD Hammer-like protocol") { // ** OBJECTS ** - DirectoryMemory directory; + DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])'; State getState(Address addr) { return directory[addr].DirectoryState; @@ -123,7 +141,7 @@ machine(Directory, "AMD Hammer-like protocol") { action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") { peek(requestQueue_in, RequestMsg) { - enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:WB_ACK; out_msg.Requestor := in_msg.Requestor; @@ -135,7 +153,7 @@ machine(Directory, "AMD Hammer-like protocol") { action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") { peek(requestQueue_in, RequestMsg) { - enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:WB_NACK; out_msg.Requestor := in_msg.Requestor; @@ -147,10 +165,10 @@ machine(Directory, "AMD Hammer-like protocol") { action(d_sendData, "d", desc="Send data to requestor") { peek(requestQueue_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=memory_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA; - out_msg.Sender := id; + out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.DataBlk := directory[in_msg.Address].DataBlk; out_msg.Dirty := false; // By definition, the block is now clean @@ -162,10 +180,10 @@ machine(Directory, "AMD Hammer-like protocol") { action(dd_sendExclusiveData, "\d", desc="Send exclusive data to requestor") { peek(requestQueue_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=memory_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; - out_msg.Sender := id; + out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); out_msg.DataBlk := directory[in_msg.Address].DataBlk; out_msg.Dirty := false; // By definition, the block is now clean @@ -176,9 +194,9 @@ machine(Directory, "AMD Hammer-like protocol") { } action(f_forwardRequest, "f", desc="Forward requests") { - if (numberOfNodes() > 1) { + if (getNumberOfLastLevelCaches() > 1) { peek(requestQueue_in, RequestMsg) { - enqueue(forwardNetwork_out, RequestMsg, latency="DIRECTORY_LATENCY") { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Requestor := in_msg.Requestor; diff --git a/src/mem/protocol/MOESI_hammer-msg.sm b/src/mem/protocol/MOESI_hammer-msg.sm index 43e00a2d1a..b4da617ccc 100644 --- a/src/mem/protocol/MOESI_hammer-msg.sm +++ b/src/mem/protocol/MOESI_hammer-msg.sm @@ -24,6 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * AMD's contributions to the MOESI hammer protocol do not constitute an + * endorsement of its similarity to any AMD products. */ // CoherenceRequestType @@ -65,7 +68,7 @@ structure(TriggerMsg, desc="...", interface="Message") { structure(RequestMsg, desc="...", interface="NetworkMessage") { Address Address, desc="Physical address for this request"; CoherenceRequestType Type, desc="Type of request (GetS, GetX, PutX, etc)"; - NodeID Requestor, desc="Node who initiated the request"; + MachineID Requestor, desc="Node who initiated the request"; NetDest Destination, desc="Multicast destination mask"; MessageSizeType MessageSize, desc="size category of the message"; } @@ -74,7 +77,7 @@ structure(RequestMsg, desc="...", interface="NetworkMessage") { structure(ResponseMsg, desc="...", interface="NetworkMessage") { Address Address, desc="Physical address for this request"; CoherenceResponseType Type, desc="Type of response (Ack, Data, etc)"; - NodeID Sender, desc="Node who sent the data"; + MachineID Sender, desc="Node who sent the data"; NetDest Destination, desc="Node to whom the data is sent"; DataBlock DataBlk, desc="data for the cache line"; bool Dirty, desc="Is the data dirty (different than memory)?"; diff --git a/src/mem/protocol/MOESI_hammer.slicc b/src/mem/protocol/MOESI_hammer.slicc index 8ff931e044..d49350e323 100644 --- a/src/mem/protocol/MOESI_hammer.slicc +++ b/src/mem/protocol/MOESI_hammer.slicc @@ -1,5 +1,4 @@ -../protocols/MOESI_hammer-msg.sm -../protocols/hammer-ni.sm -../protocols/MOESI_hammer-cache.sm -../protocols/MOESI_hammer-dir.sm -../protocols/standard_1level-node.sm +MOESI_hammer-msg.sm +MOESI_hammer-cache.sm +MOESI_hammer-dir.sm +standard_1level_CMP-protocol.sm diff --git a/src/mem/protocol/SConsopts b/src/mem/protocol/SConsopts index ded0814d28..7be9fd97e8 100644 --- a/src/mem/protocol/SConsopts +++ b/src/mem/protocol/SConsopts @@ -47,6 +47,7 @@ all_protocols = [ 'MOSI_SMP_bcast_m', 'MOSI_SMP_directory_1level', 'MSI_MOSI_CMP_directory', + 'MOESI_hammer', ] opt = EnumVariable('PROTOCOL', 'Coherence Protocol for Ruby', 'MI_example', From bc12b8432d9c576d62f6bdaabb7d78c7703a2e34 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 150/160] ruby: Hammer ruby configuration support --- src/mem/protocol/MOESI_hammer-cache.sm | 2 +- .../ruby/config/MOESI_hammer-homogeneous.rb | 109 ++++++++++++++++++ src/mem/ruby/config/MOESI_hammer.rb | 42 +++++++ src/mem/ruby/config/defaults.rb | 12 ++ 4 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 src/mem/ruby/config/MOESI_hammer-homogeneous.rb create mode 100644 src/mem/ruby/config/MOESI_hammer.rb diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index 6fb5091afe..3b22408009 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -143,7 +143,7 @@ machine(L1Cache, "AMD Hammer-like protocol") TBETable TBEs, template_hack=""; CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])'; CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])'; - CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["cache"])'; + CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["l2cache"])'; Entry getCacheEntry(Address addr), return_by_ref="yes" { if (L2cacheMemory.isTagPresent(addr)) { diff --git a/src/mem/ruby/config/MOESI_hammer-homogeneous.rb b/src/mem/ruby/config/MOESI_hammer-homogeneous.rb new file mode 100644 index 0000000000..02af0ec27a --- /dev/null +++ b/src/mem/ruby/config/MOESI_hammer-homogeneous.rb @@ -0,0 +1,109 @@ +#!/usr/bin/ruby +# +# Creates multiple on-chip nodes with three level of cache. +# + +require "cfg.rb" + +RubySystem.reset + +# default values + +num_cores = 2 +l1_cache_size_bytes = 32768 +l1_cache_assoc = 2 +l1_cache_latency = 3 +l2_cache_size_bytes = 1048576 +l2_cache_assoc = 16 +l2_cache_latency = 15 +num_memories = 2 +memory_size_mb = 1024 +num_dma = 0 +use_map = false +map_levels = 4 +protocol = "MOESI_hammer" + +# check for overrides + + +for i in 0..$*.size-1 do + if $*[i] == "-c" + protocol = $*[i+1] + i = i+1 + elsif $*[i] == "-p" + num_cores = $*[i+1].to_i + i = i+1 + elsif $*[i] == "-m" + num_memories = $*[i+1].to_i + i = i+1 + elsif $*[i] == "-s" + memory_size_mb = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-U" + use_map = $*[i+1] + i = i + 1 + elsif $*[i] == "-C" + l1_cache_size_bytes = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-A" + l1_cache_assoc = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-M" + map_levels = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-D" + num_dma = $*[i+1].to_i + i = i + 1 + end +end + +net_ports = Array.new +iface_ports = Array.new + +assert(protocol == "MOESI_hammer", __FILE__ + " cannot be used with protocol " + protocol) + +require protocol+".rb" + +num_cores.times { |n| + icache = SetAssociativeCache.new("l1i_"+n.to_s, + l1_cache_size_bytes, + l1_cache_latency, + l1_cache_assoc, + "PSEUDO_LRU") + dcache = SetAssociativeCache.new("l1d_"+n.to_s, + l1_cache_size_bytes, + l1_cache_latency, + l1_cache_assoc, + "PSEUDO_LRU") + l2cache = SetAssociativeCache.new("l2u_"+n.to_s, + l2_cache_size_bytes, + l2_cache_latency, + l2_cache_assoc, + "PSEUDO_LRU") + sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache) + iface_ports << sequencer + net_ports << MOESI_hammer_CacheController.new("L1CacheController_"+n.to_s, + "L1Cache", + icache, + dcache, + l2cache, + sequencer) +} +num_memories.times { |n| + directory = DirectoryMemory.new("DirectoryMemory_"+n.to_s, memory_size_mb/num_memories) + memory_control = MemoryControl.new("MemoryControl_"+n.to_s) + net_ports << MOESI_hammer_DirectoryController.new("DirectoryController_"+n.to_s, + "Directory", + directory, + memory_control) +} +num_dma.times { |n| + dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s) + iface_ports << dma_sequencer + net_ports << MOESI_hammer_DMAController.new("DMAController_"+n.to_s, "DMA", dma_sequencer) +} + +topology = CrossbarTopology.new("theTopology", net_ports) +on_chip_net = Network.new("theNetwork", topology) + +RubySystem.init(iface_ports, on_chip_net) diff --git a/src/mem/ruby/config/MOESI_hammer.rb b/src/mem/ruby/config/MOESI_hammer.rb new file mode 100644 index 0000000000..1e8d0d4ba9 --- /dev/null +++ b/src/mem/ruby/config/MOESI_hammer.rb @@ -0,0 +1,42 @@ + +require "util.rb" + +class MOESI_hammer_CacheController < L1CacheController + attr :cache + def initialize(obj_name, mach_type, icache, dcache, l2cache, sequencer) + super(obj_name, mach_type, [icache, dcache, l2cache], sequencer) + @icache = icache + @dcache = dcache + @l2cache = l2cache + end + def argv() + vec = super() + vec += " icache " + @icache.obj_name + vec += " dcache " + @dcache.obj_name + vec += " l2cache " + @l2cache.obj_name + vec += " issue_latency "+issue_latency.to_s + vec += " cache_response_latency "+cache_response_latency.to_s + end + +end + +class MOESI_hammer_DirectoryController < DirectoryController + def initialize(obj_name, mach_type, directory, memory_control) + super(obj_name, mach_type, directory, memory_control) + end + def argv() + vec = super() + vec += " memory_controller_latency "+memory_controller_latency.to_s + vec += " memory_latency "+memory_controller_latency.to_s + end +end + +class MOESI_hammer_DMAController < DMAController + def initialize(obj_name, mach_type, dma_sequencer) + super(obj_name, mach_type, dma_sequencer) + end + def argv() + vec = super + vec += " request_latency "+request_latency.to_s + end +end diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb index 160f254115..48169a25f4 100644 --- a/src/mem/ruby/config/defaults.rb +++ b/src/mem/ruby/config/defaults.rb @@ -167,6 +167,18 @@ class MOESI_CMP_directory_DMAController < DMAController default_param :response_latency, Integer, 6 end +## MOESI_hammer protocol + +class MOESI_hammer_CacheController < L1CacheController + default_param :issue_latency, Integer, 2 + default_param :cache_response_latency, Integer, 12 +end + +class MOESI_hammer_DirectoryController < DirectoryController + default_param :memory_controller_latency, Integer, 12 + default_param :memory_latency, Integer, 50 +end + class RubySystem # Random seed used by the simulation. If set to "rand", the seed From dbb2c111cccacad4e331bfded3b316e3c78dc63c Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 151/160] ruby: Added a memory controller feature to MOESI hammer --- src/mem/protocol/MOESI_hammer-dir.sm | 256 +++++++++++++++++++++++---- src/mem/protocol/MOESI_hammer-msg.sm | 1 + src/mem/ruby/config/MOESI_hammer.rb | 1 - src/mem/ruby/config/defaults.rb | 1 - 4 files changed, 225 insertions(+), 34 deletions(-) diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm index 0f7c58acde..49efaffb68 100644 --- a/src/mem/protocol/MOESI_hammer-dir.sm +++ b/src/mem/protocol/MOESI_hammer-dir.sm @@ -34,17 +34,16 @@ */ machine(Directory, "AMD Hammer-like protocol") -: int memory_controller_latency, - int memory_latency +: int memory_controller_latency { MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false"; MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false"; -// MessageBuffer dmaRequestFromDir, network="To", virtual_network="4", ordered="true"; + //MessageBuffer dmaRequestFromDir, network="To", virtual_network="4", ordered="true"; MessageBuffer requestToDir, network="From", virtual_network="3", ordered="false"; MessageBuffer unblockToDir, network="From", virtual_network="0", ordered="false"; -// MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true"; + //MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true"; // STATES enumeration(State, desc="Directory states", default="Directory_State_E") { @@ -54,7 +53,13 @@ machine(Directory, "AMD Hammer-like protocol") E, desc="Exclusive Owner (we can provide the data in exclusive)"; NO_B, "NO^B", desc="Not Owner, Blocked"; O_B, "O^B", desc="Owner, Blocked"; + NO_B_W, desc="Not Owner, Blocked, waiting for Dram"; + O_B_W, desc="Owner, Blocked, waiting for Dram"; + NO_W, desc="Not Owner, waiting for Dram"; + O_W, desc="Owner, waiting for Dram"; WB, desc="Blocked on a writeback"; + WB_O_W, desc="Blocked on memory write, will go to O"; + WB_E_W, desc="Blocked on memory write, will go to E"; } // Events @@ -67,6 +72,10 @@ machine(Directory, "AMD Hammer-like protocol") Writeback_Dirty, desc="The final part of a PutX (data)"; Writeback_Exclusive_Clean, desc="The final part of a PutX (no data, exclusive)"; Writeback_Exclusive_Dirty, desc="The final part of a PutX (data, exclusive)"; + + // Memory Controller + Memory_Data, desc="Fetched data from memory arrives"; + Memory_Ack, desc="Writeback Ack from memory arrives"; } // TYPES @@ -82,15 +91,47 @@ machine(Directory, "AMD Hammer-like protocol") bool isPresent(Address); } + external_type(MemoryControl, inport="yes", outport="yes") { + + } + + // TBE entries for DMA requests + structure(TBE, desc="TBE entries for outstanding DMA requests") { + Address PhysicalAddress, desc="physical address"; + State TBEState, desc="Transient State"; + CoherenceResponseType ResponseType, desc="The type for the subsequent response message"; + DataBlock DataBlk, desc="Data to be written (DMA write only)"; + int Len, desc="..."; + MachineID DmaRequestor, desc="DMA requestor"; + } + + external_type(TBETable) { + TBE lookup(Address); + void allocate(Address); + void deallocate(Address); + bool isPresent(Address); + } + // ** OBJECTS ** DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])'; + MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])'; + + TBETable TBEs, template_hack=""; + State getState(Address addr) { - return directory[addr].DirectoryState; + if (TBEs.isPresent(addr)) { + return TBEs[addr].TBEState; + } else { + return directory[addr].DirectoryState; + } } void setState(Address addr, State state) { + if (TBEs.isPresent(addr)) { + TBEs[addr].TBEState := state; + } directory[addr].DirectoryState := state; } @@ -99,6 +140,11 @@ machine(Directory, "AMD Hammer-like protocol") out_port(responseNetwork_out, ResponseMsg, responseFromDir); out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests + // + // Memory buffer for memory controller to DIMM communication + // + out_port(memQueue_out, MemoryMsg, memBuffer); + // ** IN_PORTS ** in_port(unblockNetwork_in, ResponseMsg, unblockToDir) { @@ -137,6 +183,22 @@ machine(Directory, "AMD Hammer-like protocol") } } + // off-chip memory request/response is done + in_port(memQueue_in, MemoryMsg, memBuffer) { + if (memQueue_in.isReady()) { + peek(memQueue_in, MemoryMsg) { + if (in_msg.Type == MemoryRequestType:MEMORY_READ) { + trigger(Event:Memory_Data, in_msg.Address); + } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) { + trigger(Event:Memory_Ack, in_msg.Address); + } else { + DEBUG_EXPR(in_msg.Type); + error("Invalid message"); + } + } + } + } + // Actions action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") { @@ -163,14 +225,26 @@ machine(Directory, "AMD Hammer-like protocol") } } - action(d_sendData, "d", desc="Send data to requestor") { + action(v_allocateTBE, "v", desc="Allocate TBE") { peek(requestQueue_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency=memory_latency) { + TBEs.allocate(address); + TBEs[address].PhysicalAddress := address; + TBEs[address].ResponseType := CoherenceResponseType:NULL; + } + } + + action(w_deallocateTBE, "w", desc="Deallocate TBE") { + TBEs.deallocate(address); + } + + action(d_sendData, "d", desc="Send data to requestor") { + peek(memQueue_in, MemoryMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; - out_msg.Type := CoherenceResponseType:DATA; + out_msg.Type := TBEs[address].ResponseType; out_msg.Sender := machineID; - out_msg.Destination.add(in_msg.Requestor); - out_msg.DataBlk := directory[in_msg.Address].DataBlk; + out_msg.Destination.add(in_msg.OriginalRequestorMachId); + out_msg.DataBlk := in_msg.DataBlk; out_msg.Dirty := false; // By definition, the block is now clean out_msg.Acks := 1; out_msg.MessageSize := MessageSizeType:Response_Data; @@ -178,21 +252,77 @@ machine(Directory, "AMD Hammer-like protocol") } } - action(dd_sendExclusiveData, "\d", desc="Send exclusive data to requestor") { + action(rx_recordExclusiveInTBE, "rx", desc="Record Exclusive in TBE") { peek(requestQueue_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency=memory_latency) { + TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE; + } + } + + action(r_recordDataInTBE, "r", desc="Record Data in TBE") { + peek(requestQueue_in, RequestMsg) { + TBEs[address].ResponseType := CoherenceResponseType:DATA; + } + } + + action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { + peek(requestQueue_in, RequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { out_msg.Address := address; - out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; + out_msg.Type := MemoryRequestType:MEMORY_READ; out_msg.Sender := machineID; - out_msg.Destination.add(in_msg.Requestor); + out_msg.OriginalRequestorMachId := in_msg.Requestor; + out_msg.MessageSize := in_msg.MessageSize; out_msg.DataBlk := directory[in_msg.Address].DataBlk; - out_msg.Dirty := false; // By definition, the block is now clean - out_msg.Acks := 1; - out_msg.MessageSize := MessageSizeType:Response_Data; + DEBUG_EXPR(out_msg); } } } +// action(qx_queueMemoryFetchExclusiveRequest, "xf", desc="Queue off-chip fetch request") { +// peek(requestQueue_in, RequestMsg) { +// enqueue(memQueue_out, MemoryMsg, latency=memory_request_latency) { +// out_msg.Address := address; +// out_msg.Type := MemoryRequestType:MEMORY_READ; +// out_msg.ResponseType := CoherenceResponseType:DATA_EXCLUSIVE; +// out_msg.Sender := machineID; +// out_msg.OriginalRequestorMachId := in_msg.Requestor; +// out_msg.MessageSize := in_msg.MessageSize; +// out_msg.DataBlk := directory[in_msg.Address].DataBlk; +// DEBUG_EXPR(out_msg); +// } +// } +// } + +// action(d_sendData, "d", desc="Send data to requestor") { +// peek(requestQueue_in, RequestMsg) { +// enqueue(responseNetwork_out, ResponseMsg, latency=memory_latency) { +// out_msg.Address := address; +// out_msg.Type := CoherenceResponseType:DATA; +// out_msg.Sender := machineID; +// out_msg.Destination.add(in_msg.Requestor); +// out_msg.DataBlk := directory[in_msg.Address].DataBlk; +// out_msg.Dirty := false; // By definition, the block is now clean +// out_msg.Acks := 1; +// out_msg.MessageSize := MessageSizeType:Response_Data; +// } +// } +// } + +// action(dd_sendExclusiveData, "\d", desc="Send exclusive data to requestor") { +// peek(requestQueue_in, RequestMsg) { +// enqueue(responseNetwork_out, ResponseMsg, latency=memory_latency) { +// out_msg.Address := address; +// out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; +// out_msg.Sender := machineID; +// out_msg.Destination.add(in_msg.Requestor); +// out_msg.DataBlk := directory[in_msg.Address].DataBlk; +// out_msg.Dirty := false; // By definition, the block is now clean +// out_msg.Acks := 1; +// out_msg.MessageSize := MessageSizeType:Response_Data; +// } +// } +// } + action(f_forwardRequest, "f", desc="Forward requests") { if (getNumberOfLastLevelCaches() > 1) { peek(requestQueue_in, RequestMsg) { @@ -200,7 +330,7 @@ machine(Directory, "AMD Hammer-like protocol") out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Requestor := in_msg.Requestor; - out_msg.Destination.broadcast(); // Send to everyone, but... + out_msg.Destination.broadcast(MachineType:L1Cache); // Send to all L1 caches out_msg.Destination.remove(in_msg.Requestor); // Don't include the original requestor out_msg.MessageSize := MessageSizeType:Forwarded_Control; } @@ -216,6 +346,10 @@ machine(Directory, "AMD Hammer-like protocol") unblockNetwork_in.dequeue(); } + action(l_popMemQueue, "q", desc="Pop off-chip request queue") { + memQueue_in.dequeue(); + } + action(l_writeDataToMemory, "l", desc="Write PUTX/PUTO data to memory") { peek(unblockNetwork_in, ResponseMsg) { assert(in_msg.Dirty); @@ -226,6 +360,16 @@ machine(Directory, "AMD Hammer-like protocol") } } + action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") { + peek(unblockNetwork_in, ResponseMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + DEBUG_EXPR(out_msg); + } + } + } + action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") { peek(unblockNetwork_in, ResponseMsg) { assert(in_msg.Dirty == false); @@ -249,27 +393,35 @@ machine(Directory, "AMD Hammer-like protocol") // TRANSITIONS - transition(E, GETX, NO_B) { - dd_sendExclusiveData; + transition(E, GETX, NO_B_W) { + v_allocateTBE; + rx_recordExclusiveInTBE; + qf_queueMemoryFetchRequest; f_forwardRequest; i_popIncomingRequestQueue; } - transition(E, GETS, NO_B) { - dd_sendExclusiveData; + transition(E, GETS, NO_B_W) { + v_allocateTBE; + rx_recordExclusiveInTBE; + qf_queueMemoryFetchRequest; f_forwardRequest; i_popIncomingRequestQueue; } // - transition(O, GETX, NO_B) { - d_sendData; + transition(O, GETX, NO_B_W) { + v_allocateTBE; + r_recordDataInTBE; + qf_queueMemoryFetchRequest; f_forwardRequest; i_popIncomingRequestQueue; } - transition(O, GETS, O_B) { - d_sendData; + transition(O, GETS, O_B_W) { + v_allocateTBE; + r_recordDataInTBE; + qf_queueMemoryFetchRequest; f_forwardRequest; i_popIncomingRequestQueue; } @@ -296,7 +448,7 @@ machine(Directory, "AMD Hammer-like protocol") } // Blocked states - transition({NO_B, O_B, WB}, {GETS, GETX, PUT}) { + transition({NO_B, O_B, NO_B_W, O_B_W, NO_W, O_W, WB, WB_E_W, WB_O_W}, {GETS, GETX, PUT}) { zz_recycleRequest; } @@ -308,17 +460,57 @@ machine(Directory, "AMD Hammer-like protocol") j_popIncomingUnblockQueue; } - // WB - transition(WB, Writeback_Dirty, O) { - l_writeDataToMemory; + transition(NO_B_W, Memory_Data, NO_B) { + d_sendData; + w_deallocateTBE; + l_popMemQueue; + } + + transition(O_B_W, Memory_Data, O_B) { + d_sendData; + w_deallocateTBE; + l_popMemQueue; + } + + transition(NO_B_W, Unblock, NO_W) { j_popIncomingUnblockQueue; } - transition(WB, Writeback_Exclusive_Dirty, E) { - l_writeDataToMemory; + transition(O_B_W, Unblock, O_W) { j_popIncomingUnblockQueue; } + transition(NO_W, Memory_Data, NO) { + w_deallocateTBE; + l_popMemQueue; + } + + transition(O_W, Memory_Data, O) { + w_deallocateTBE; + l_popMemQueue; + } + + // WB + transition(WB, Writeback_Dirty, WB_E_W) { + l_writeDataToMemory; + l_queueMemoryWBRequest; + j_popIncomingUnblockQueue; + } + + transition(WB, Writeback_Exclusive_Dirty, WB_O_W) { + l_writeDataToMemory; + l_queueMemoryWBRequest; + j_popIncomingUnblockQueue; + } + + transition(WB_E_W, Memory_Ack, E) { + l_popMemQueue; + } + + transition(WB_O_W, Memory_Ack, O) { + l_popMemQueue; + } + transition(WB, Writeback_Clean, O) { ll_checkIncomingWriteback; j_popIncomingUnblockQueue; diff --git a/src/mem/protocol/MOESI_hammer-msg.sm b/src/mem/protocol/MOESI_hammer-msg.sm index b4da617ccc..c9f1468198 100644 --- a/src/mem/protocol/MOESI_hammer-msg.sm +++ b/src/mem/protocol/MOESI_hammer-msg.sm @@ -50,6 +50,7 @@ enumeration(CoherenceResponseType, desc="...") { WB_EXCLUSIVE_CLEAN, desc="Clean writeback of exclusive data"; WB_EXCLUSIVE_DIRTY, desc="Dirty writeback of exclusive data"; UNBLOCK, desc="Unblock"; + NULL, desc="Null value"; } // TriggerType diff --git a/src/mem/ruby/config/MOESI_hammer.rb b/src/mem/ruby/config/MOESI_hammer.rb index 1e8d0d4ba9..d3735028bf 100644 --- a/src/mem/ruby/config/MOESI_hammer.rb +++ b/src/mem/ruby/config/MOESI_hammer.rb @@ -27,7 +27,6 @@ class MOESI_hammer_DirectoryController < DirectoryController def argv() vec = super() vec += " memory_controller_latency "+memory_controller_latency.to_s - vec += " memory_latency "+memory_controller_latency.to_s end end diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb index 48169a25f4..da7fa17c74 100644 --- a/src/mem/ruby/config/defaults.rb +++ b/src/mem/ruby/config/defaults.rb @@ -176,7 +176,6 @@ end class MOESI_hammer_DirectoryController < DirectoryController default_param :memory_controller_latency, Integer, 12 - default_param :memory_latency, Integer, 50 end class RubySystem From cef3c5616358912b45aafac490bf182c1a8def04 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 152/160] ruby: MOESI hammer support for DMA reads and writes --- src/mem/protocol/MOESI_hammer-dir.sm | 517 +++++++++++++++++++++++---- src/mem/protocol/MOESI_hammer-dma.sm | 165 +++++++++ src/mem/protocol/MOESI_hammer-msg.sm | 32 ++ src/mem/protocol/MOESI_hammer.slicc | 1 + src/mem/ruby/config/defaults.rb | 4 + 5 files changed, 657 insertions(+), 62 deletions(-) create mode 100644 src/mem/protocol/MOESI_hammer-dma.sm diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm index 49efaffb68..b9b001e401 100644 --- a/src/mem/protocol/MOESI_hammer-dir.sm +++ b/src/mem/protocol/MOESI_hammer-dir.sm @@ -39,11 +39,17 @@ machine(Directory, "AMD Hammer-like protocol") MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false"; MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false"; - //MessageBuffer dmaRequestFromDir, network="To", virtual_network="4", ordered="true"; + // + // For a finite buffered network, note that the DMA response network only + // works at this relatively higher numbered (lower priority) virtual network + // because the trigger queue decouples cache responses from DMA responses. + // + MessageBuffer dmaResponseFromDir, network="To", virtual_network="4", ordered="true"; - MessageBuffer requestToDir, network="From", virtual_network="3", ordered="false"; MessageBuffer unblockToDir, network="From", virtual_network="0", ordered="false"; - //MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true"; + MessageBuffer responseToDir, network="From", virtual_network="1", ordered="false"; + MessageBuffer requestToDir, network="From", virtual_network="3", ordered="false"; + MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true"; // STATES enumeration(State, desc="Directory states", default="Directory_State_E") { @@ -57,6 +63,13 @@ machine(Directory, "AMD Hammer-like protocol") O_B_W, desc="Owner, Blocked, waiting for Dram"; NO_W, desc="Not Owner, waiting for Dram"; O_W, desc="Owner, waiting for Dram"; + NO_DW_B_W, desc="Not Owner, Dma Write waiting for Dram and cache responses"; + NO_DR_B_W, desc="Not Owner, Dma Read waiting for Dram and cache responses"; + NO_DR_B_D, desc="Not Owner, Dma Read waiting for cache responses including dirty data"; + NO_DR_B, desc="Not Owner, Dma Read waiting for cache responses"; + NO_DW_W, desc="Not Owner, Dma Write waiting for Dram"; + O_DR_B_W, desc="Owner, Dma Read waiting for Dram and cache responses"; + O_DR_B, desc="Owner, Dma Read waiting for cache responses"; WB, desc="Blocked on a writeback"; WB_O_W, desc="Blocked on memory write, will go to O"; WB_E_W, desc="Blocked on memory write, will go to E"; @@ -73,9 +86,23 @@ machine(Directory, "AMD Hammer-like protocol") Writeback_Exclusive_Clean, desc="The final part of a PutX (no data, exclusive)"; Writeback_Exclusive_Dirty, desc="The final part of a PutX (data, exclusive)"; + // DMA requests + DMA_READ, desc="A DMA Read memory request"; + DMA_WRITE, desc="A DMA Write memory request"; + // Memory Controller Memory_Data, desc="Fetched data from memory arrives"; Memory_Ack, desc="Writeback Ack from memory arrives"; + + // Cache responses required to handle DMA + Ack, desc="Received an ack message"; + Shared_Ack, desc="Received an ack message, responder has a shared copy"; + Shared_Data, desc="Received a data message, responder has a shared copy"; + Exclusive_Data, desc="Received a data message, responder had an exclusive copy, they gave it to us"; + + // Triggers + All_acks_and_data, desc="Received all required data and message acks"; + All_acks_and_data_no_sharers, desc="Received all acks and no other processor has a shared copy"; } // TYPES @@ -100,9 +127,13 @@ machine(Directory, "AMD Hammer-like protocol") Address PhysicalAddress, desc="physical address"; State TBEState, desc="Transient State"; CoherenceResponseType ResponseType, desc="The type for the subsequent response message"; - DataBlock DataBlk, desc="Data to be written (DMA write only)"; + DataBlock DmaDataBlk, desc="DMA Data to be written. Partial blocks need to merged with system memory"; + DataBlock DataBlk, desc="The current view of system memory"; int Len, desc="..."; MachineID DmaRequestor, desc="DMA requestor"; + int NumPendingMsgs, desc="Number of pending acks/messages"; + bool CacheDirty, desc="Indicates whether a cache has responded with dirty data"; + bool Sharers, desc="Indicates whether a cache has indicated it is currently a sharer"; } external_type(TBETable) { @@ -135,10 +166,14 @@ machine(Directory, "AMD Hammer-like protocol") directory[addr].DirectoryState := state; } + MessageBuffer triggerQueue, ordered="true"; + // ** OUT_PORTS ** + out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests out_port(forwardNetwork_out, RequestMsg, forwardFromDir); out_port(responseNetwork_out, ResponseMsg, responseFromDir); - out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests + out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir); + out_port(triggerQueue_out, TriggerMsg, triggerQueue); // // Memory buffer for memory controller to DIMM communication @@ -147,6 +182,21 @@ machine(Directory, "AMD Hammer-like protocol") // ** IN_PORTS ** + // Trigger Queue + in_port(triggerQueue_in, TriggerMsg, triggerQueue) { + if (triggerQueue_in.isReady()) { + peek(triggerQueue_in, TriggerMsg) { + if (in_msg.Type == TriggerType:ALL_ACKS) { + trigger(Event:All_acks_and_data, in_msg.Address); + } else if (in_msg.Type == TriggerType:ALL_ACKS_NO_SHARERS) { + trigger(Event:All_acks_and_data_no_sharers, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + in_port(unblockNetwork_in, ResponseMsg, unblockToDir) { if (unblockNetwork_in.isReady()) { peek(unblockNetwork_in, ResponseMsg) { @@ -167,6 +217,39 @@ machine(Directory, "AMD Hammer-like protocol") } } + // Response Network + in_port(responseToDir_in, ResponseMsg, responseToDir) { + if (responseToDir_in.isReady()) { + peek(responseToDir_in, ResponseMsg) { + if (in_msg.Type == CoherenceResponseType:ACK) { + trigger(Event:Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK_SHARED) { + trigger(Event:Shared_Ack, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) { + trigger(Event:Shared_Data, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { + trigger(Event:Exclusive_Data, in_msg.Address); + } else { + error("Unexpected message"); + } + } + } + } + + in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) { + if (dmaRequestQueue_in.isReady()) { + peek(dmaRequestQueue_in, DMARequestMsg) { + if (in_msg.Type == DMARequestType:READ) { + trigger(Event:DMA_READ, in_msg.LineAddress); + } else if (in_msg.Type == DMARequestType:WRITE) { + trigger(Event:DMA_WRITE, in_msg.LineAddress); + } else { + error("Invalid message"); + } + } + } + } + in_port(requestQueue_in, RequestMsg, requestToDir) { if (requestQueue_in.isReady()) { peek(requestQueue_in, RequestMsg) { @@ -233,10 +316,61 @@ machine(Directory, "AMD Hammer-like protocol") } } + action(vd_allocateDmaRequestInTBE, "vd", desc="Record Data in TBE") { + peek(dmaRequestQueue_in, DMARequestMsg) { + TBEs.allocate(address); + TBEs[address].DmaDataBlk := in_msg.DataBlk; + TBEs[address].PhysicalAddress := in_msg.PhysicalAddress; + TBEs[address].Len := in_msg.Len; + TBEs[address].DmaRequestor := in_msg.Requestor; + TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE; + // + // One ack for each last-level cache + // + TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches(); + // + // Assume initially that the caches store a clean copy and that memory + // will provide the data + // + TBEs[address].CacheDirty := false; + } + } + action(w_deallocateTBE, "w", desc="Deallocate TBE") { TBEs.deallocate(address); } + action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") { + peek(responseToDir_in, ResponseMsg) { + assert(in_msg.Acks > 0); + DEBUG_EXPR(TBEs[address].NumPendingMsgs); + // + // Note that cache data responses will have an ack count of 2. However, + // directory DMA requests must wait for acks from all LLC caches, so + // only decrement by 1. + // + TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - 1; + DEBUG_EXPR(TBEs[address].NumPendingMsgs); + } + } + + action(n_popResponseQueue, "n", desc="Pop response queue") { + responseToDir_in.dequeue(); + } + + action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") { + if (TBEs[address].NumPendingMsgs == 0) { + enqueue(triggerQueue_out, TriggerMsg) { + out_msg.Address := address; + if (TBEs[address].Sharers) { + out_msg.Type := TriggerType:ALL_ACKS; + } else { + out_msg.Type := TriggerType:ALL_ACKS_NO_SHARERS; + } + } + } + } + action(d_sendData, "d", desc="Send data to requestor") { peek(memQueue_in, MemoryMsg) { enqueue(responseNetwork_out, ResponseMsg, latency="1") { @@ -252,18 +386,66 @@ machine(Directory, "AMD Hammer-like protocol") } } + action(dr_sendDmaData, "dr", desc="Send Data to DMA controller from memory") { + peek(memQueue_in, MemoryMsg) { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:DATA; + // + // we send the entire data block and rely on the dma controller to + // split it up if need be + // + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(dt_sendDmaDataFromTbe, "dt", desc="Send Data to DMA controller from tbe") { + peek(triggerQueue_in, TriggerMsg) { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:DATA; + // + // we send the entire data block and rely on the dma controller to + // split it up if need be + // + out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(da_sendDmaAck, "da", desc="Send Ack to DMA controller") { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:ACK; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + action(rx_recordExclusiveInTBE, "rx", desc="Record Exclusive in TBE") { peek(requestQueue_in, RequestMsg) { TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE; } } - action(r_recordDataInTBE, "r", desc="Record Data in TBE") { + action(r_recordDataInTBE, "rt", desc="Record Data in TBE") { peek(requestQueue_in, RequestMsg) { TBEs[address].ResponseType := CoherenceResponseType:DATA; } } + action(r_setSharerBit, "r", desc="We saw other sharers") { + TBEs[address].Sharers := true; + } + action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { peek(requestQueue_in, RequestMsg) { enqueue(memQueue_out, MemoryMsg, latency="1") { @@ -272,56 +454,25 @@ machine(Directory, "AMD Hammer-like protocol") out_msg.Sender := machineID; out_msg.OriginalRequestorMachId := in_msg.Requestor; out_msg.MessageSize := in_msg.MessageSize; - out_msg.DataBlk := directory[in_msg.Address].DataBlk; + out_msg.DataBlk := directory[address].DataBlk; DEBUG_EXPR(out_msg); } } } -// action(qx_queueMemoryFetchExclusiveRequest, "xf", desc="Queue off-chip fetch request") { -// peek(requestQueue_in, RequestMsg) { -// enqueue(memQueue_out, MemoryMsg, latency=memory_request_latency) { -// out_msg.Address := address; -// out_msg.Type := MemoryRequestType:MEMORY_READ; -// out_msg.ResponseType := CoherenceResponseType:DATA_EXCLUSIVE; -// out_msg.Sender := machineID; -// out_msg.OriginalRequestorMachId := in_msg.Requestor; -// out_msg.MessageSize := in_msg.MessageSize; -// out_msg.DataBlk := directory[in_msg.Address].DataBlk; -// DEBUG_EXPR(out_msg); -// } -// } -// } - -// action(d_sendData, "d", desc="Send data to requestor") { -// peek(requestQueue_in, RequestMsg) { -// enqueue(responseNetwork_out, ResponseMsg, latency=memory_latency) { -// out_msg.Address := address; -// out_msg.Type := CoherenceResponseType:DATA; -// out_msg.Sender := machineID; -// out_msg.Destination.add(in_msg.Requestor); -// out_msg.DataBlk := directory[in_msg.Address].DataBlk; -// out_msg.Dirty := false; // By definition, the block is now clean -// out_msg.Acks := 1; -// out_msg.MessageSize := MessageSizeType:Response_Data; -// } -// } -// } - -// action(dd_sendExclusiveData, "\d", desc="Send exclusive data to requestor") { -// peek(requestQueue_in, RequestMsg) { -// enqueue(responseNetwork_out, ResponseMsg, latency=memory_latency) { -// out_msg.Address := address; -// out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; -// out_msg.Sender := machineID; -// out_msg.Destination.add(in_msg.Requestor); -// out_msg.DataBlk := directory[in_msg.Address].DataBlk; -// out_msg.Dirty := false; // By definition, the block is now clean -// out_msg.Acks := 1; -// out_msg.MessageSize := MessageSizeType:Response_Data; -// } -// } -// } + action(qd_queueMemoryRequestFromDmaRead, "qd", desc="Queue off-chip fetch request") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := in_msg.Requestor; + out_msg.MessageSize := in_msg.MessageSize; + out_msg.DataBlk := directory[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + } action(f_forwardRequest, "f", desc="Forward requests") { if (getNumberOfLastLevelCaches() > 1) { @@ -338,6 +489,38 @@ machine(Directory, "AMD Hammer-like protocol") } } + action(f_forwardWriteFromDma, "fw", desc="Forward requests") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETX; + // + // Send to all L1 caches, since the requestor is the memory controller + // itself + // + out_msg.Requestor := machineID; + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.MessageSize := MessageSizeType:Forwarded_Control; + } + } + } + + action(f_forwardReadFromDma, "fr", desc="Forward requests") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETS; + // + // Send to all L1 caches, since the requestor is the memory controller + // itself + // + out_msg.Requestor := machineID; + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.MessageSize := MessageSizeType:Forwarded_Control; + } + } + } + action(i_popIncomingRequestQueue, "i", desc="Pop incoming request queue") { requestQueue_in.dequeue(); } @@ -350,16 +533,52 @@ machine(Directory, "AMD Hammer-like protocol") memQueue_in.dequeue(); } + action(g_popTriggerQueue, "g", desc="Pop trigger queue") { + triggerQueue_in.dequeue(); + } + + action(p_popDmaRequestQueue, "pd", desc="pop dma request queue") { + dmaRequestQueue_in.dequeue(); + } + + action(y_recycleDmaRequestQueue, "y", desc="recycle dma request queue") { + dmaRequestQueue_in.recycle(); + } + + action(r_recordMemoryData, "rd", desc="record data from memory to TBE") { + peek(memQueue_in, MemoryMsg) { + if (TBEs[address].CacheDirty == false) { + TBEs[address].DataBlk := in_msg.DataBlk; + } + } + } + + action(r_recordCacheData, "rc", desc="record data from cache response to TBE") { + peek(responseToDir_in, ResponseMsg) { + TBEs[address].CacheDirty := true; + TBEs[address].DataBlk := in_msg.DataBlk; + } + } + action(l_writeDataToMemory, "l", desc="Write PUTX/PUTO data to memory") { peek(unblockNetwork_in, ResponseMsg) { assert(in_msg.Dirty); assert(in_msg.MessageSize == MessageSizeType:Writeback_Data); - directory[in_msg.Address].DataBlk := in_msg.DataBlk; + directory[address].DataBlk := in_msg.DataBlk; DEBUG_EXPR(in_msg.Address); DEBUG_EXPR(in_msg.DataBlk); } } + action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") { + directory[address].DataBlk := TBEs[address].DataBlk; + directory[address].DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + } + + action(a_assertCacheData, "ac", desc="Assert that a cache provided the data") { + assert(TBEs[address].CacheDirty); + } + action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") { peek(unblockNetwork_in, ResponseMsg) { enqueue(memQueue_out, MemoryMsg, latency="1") { @@ -370,6 +589,18 @@ machine(Directory, "AMD Hammer-like protocol") } } + action(ld_queueMemoryDmaWrite, "ld", desc="Write DMA data to memory") { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + // first, initialize the data blk to the current version of system memory + out_msg.DataBlk := TBEs[address].DataBlk; + // then add the dma write data + out_msg.DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + DEBUG_EXPR(out_msg); + } + } + action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") { peek(unblockNetwork_in, ResponseMsg) { assert(in_msg.Dirty == false); @@ -379,20 +610,17 @@ machine(Directory, "AMD Hammer-like protocol") // implementation. We include the data in the "dataless" // message so we can assert the clean data matches the datablock // in memory - assert(directory[in_msg.Address].DataBlk == in_msg.DataBlk); + assert(directory[address].DataBlk == in_msg.DataBlk); } } - // action(z_stall, "z", desc="Cannot be handled right now.") { - // Special name recognized as do nothing case - // } - action(zz_recycleRequest, "\z", desc="Recycle the request queue") { requestQueue_in.recycle(); } // TRANSITIONS + // Transitions out of E state transition(E, GETX, NO_B_W) { v_allocateTBE; rx_recordExclusiveInTBE; @@ -409,7 +637,14 @@ machine(Directory, "AMD Hammer-like protocol") i_popIncomingRequestQueue; } - // + transition(E, DMA_READ, NO_DR_B_W) { + vd_allocateDmaRequestInTBE; + qd_queueMemoryRequestFromDmaRead; + f_forwardReadFromDma; + p_popDmaRequestQueue; + } + + // Transitions out of O state transition(O, GETX, NO_B_W) { v_allocateTBE; r_recordDataInTBE; @@ -426,7 +661,20 @@ machine(Directory, "AMD Hammer-like protocol") i_popIncomingRequestQueue; } - // + transition(O, DMA_READ, O_DR_B_W) { + vd_allocateDmaRequestInTBE; + qd_queueMemoryRequestFromDmaRead; + f_forwardReadFromDma; + p_popDmaRequestQueue; + } + + transition({E, O, NO}, DMA_WRITE, NO_DW_B_W) { + vd_allocateDmaRequestInTBE; + f_forwardWriteFromDma; + p_popDmaRequestQueue; + } + + // Transitions out of NO state transition(NO, GETX, NO_B) { f_forwardRequest; i_popIncomingRequestQueue; @@ -442,16 +690,33 @@ machine(Directory, "AMD Hammer-like protocol") i_popIncomingRequestQueue; } + transition(NO, DMA_READ, NO_DR_B_D) { + vd_allocateDmaRequestInTBE; + f_forwardReadFromDma; + p_popDmaRequestQueue; + } + + // Nack PUT requests when races cause us to believe we own the data transition({O, E}, PUT) { b_sendWriteBackNack; i_popIncomingRequestQueue; } - // Blocked states - transition({NO_B, O_B, NO_B_W, O_B_W, NO_W, O_W, WB, WB_E_W, WB_O_W}, {GETS, GETX, PUT}) { + // Blocked transient states + transition({NO_B, O_B, NO_DR_B_W, NO_DW_B_W, NO_B_W, NO_DR_B_D, + NO_DR_B, O_DR_B, O_B_W, O_DR_B_W, NO_DW_W, + NO_W, O_W, WB, WB_E_W, WB_O_W}, + {GETS, GETX, PUT}) { zz_recycleRequest; } + transition({NO_B, O_B, NO_DR_B_W, NO_DW_B_W, NO_B_W, NO_DR_B_D, + NO_DR_B, O_DR_B, O_B_W, O_DR_B_W, NO_DW_W, + NO_W, O_W, WB, WB_E_W, WB_O_W}, + {DMA_READ, DMA_WRITE}) { + y_recycleDmaRequestQueue; + } + transition(NO_B, Unblock, NO) { j_popIncomingUnblockQueue; } @@ -466,6 +731,134 @@ machine(Directory, "AMD Hammer-like protocol") l_popMemQueue; } + transition(NO_DR_B_W, Memory_Data, NO_DR_B) { + r_recordMemoryData; + o_checkForCompletion; + l_popMemQueue; + } + + transition(O_DR_B_W, Memory_Data, O_DR_B) { + r_recordMemoryData; + dr_sendDmaData; + o_checkForCompletion; + l_popMemQueue; + } + + transition({NO_DR_B, O_DR_B, NO_DR_B_D, NO_DW_B_W}, Ack) { + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(NO_DR_B_W, Ack) { + m_decrementNumberOfMessages; + n_popResponseQueue; + } + + transition(NO_DR_B_W, Shared_Ack) { + m_decrementNumberOfMessages; + r_setSharerBit; + n_popResponseQueue; + } + + transition({NO_DR_B, NO_DR_B_D}, Shared_Ack) { + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(NO_DR_B_W, Shared_Data) { + r_recordCacheData; + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition({NO_DR_B, NO_DR_B_D}, Shared_Data) { + r_recordCacheData; + m_decrementNumberOfMessages; + r_setSharerBit; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(NO_DR_B_W, Exclusive_Data) { + r_recordCacheData; + m_decrementNumberOfMessages; + n_popResponseQueue; + } + + transition({NO_DR_B, NO_DR_B_D, NO_DW_B_W}, Exclusive_Data) { + r_recordCacheData; + m_decrementNumberOfMessages; + o_checkForCompletion; + n_popResponseQueue; + } + + transition(NO_DR_B, All_acks_and_data, O) { + // + // Note that the DMA consistency model allows us to send the DMA device + // a response as soon as we receive valid data and prior to receiving + // all acks. However, to simplify the protocol we wait for all acks. + // + dt_sendDmaDataFromTbe; + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(NO_DR_B_D, All_acks_and_data, O) { + // + // Note that the DMA consistency model allows us to send the DMA device + // a response as soon as we receive valid data and prior to receiving + // all acks. However, to simplify the protocol we wait for all acks. + // + dt_sendDmaDataFromTbe; + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(O_DR_B, All_acks_and_data_no_sharers, O) { + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(NO_DR_B, All_acks_and_data_no_sharers, E) { + // + // Note that the DMA consistency model allows us to send the DMA device + // a response as soon as we receive valid data and prior to receiving + // all acks. However, to simplify the protocol we wait for all acks. + // + dt_sendDmaDataFromTbe; + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(NO_DR_B_D, All_acks_and_data_no_sharers, E) { + a_assertCacheData; + // + // Note that the DMA consistency model allows us to send the DMA device + // a response as soon as we receive valid data and prior to receiving + // all acks. However, to simplify the protocol we wait for all acks. + // + dt_sendDmaDataFromTbe; + w_deallocateTBE; + g_popTriggerQueue; + } + + transition(NO_DW_B_W, All_acks_and_data_no_sharers, NO_DW_W) { + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWrite; + g_popTriggerQueue; + } + + transition(NO_DW_W, Memory_Ack, E) { + da_sendDmaAck; + w_deallocateTBE; + l_popMemQueue; + } + transition(O_B_W, Memory_Data, O_B) { d_sendData; w_deallocateTBE; @@ -490,7 +883,7 @@ machine(Directory, "AMD Hammer-like protocol") l_popMemQueue; } - // WB + // WB State Transistions transition(WB, Writeback_Dirty, WB_E_W) { l_writeDataToMemory; l_queueMemoryWBRequest; diff --git a/src/mem/protocol/MOESI_hammer-dma.sm b/src/mem/protocol/MOESI_hammer-dma.sm new file mode 100644 index 0000000000..b217923a4b --- /dev/null +++ b/src/mem/protocol/MOESI_hammer-dma.sm @@ -0,0 +1,165 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +machine(DMA, "DMA Controller") +: int request_latency +{ + + MessageBuffer responseFromDir, network="From", virtual_network="4", ordered="true", no_vector="true"; + MessageBuffer reqToDirectory, network="To", virtual_network="5", ordered="false", no_vector="true"; + + enumeration(State, desc="DMA states", default="DMA_State_READY") { + READY, desc="Ready to accept a new request"; + BUSY_RD, desc="Busy: currently processing a request"; + BUSY_WR, desc="Busy: currently processing a request"; + } + + enumeration(Event, desc="DMA events") { + ReadRequest, desc="A new read request"; + WriteRequest, desc="A new write request"; + Data, desc="Data from a DMA memory read"; + Ack, desc="DMA write to memory completed"; + } + + external_type(DMASequencer) { + void ackCallback(); + void dataCallback(DataBlock); + } + + MessageBuffer mandatoryQueue, ordered="false", no_vector="true"; + DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])', no_vector="true"; + State cur_state, no_vector="true"; + + State getState(Address addr) { + return cur_state; + } + void setState(Address addr, State state) { + cur_state := state; + } + + out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="..."); + + in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") { + if (dmaRequestQueue_in.isReady()) { + peek(dmaRequestQueue_in, SequencerMsg) { + if (in_msg.Type == SequencerRequestType:LD ) { + trigger(Event:ReadRequest, in_msg.LineAddress); + } else if (in_msg.Type == SequencerRequestType:ST) { + trigger(Event:WriteRequest, in_msg.LineAddress); + } else { + error("Invalid request type"); + } + } + } + } + + in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") { + if (dmaResponseQueue_in.isReady()) { + peek( dmaResponseQueue_in, DMAResponseMsg) { + if (in_msg.Type == DMAResponseType:ACK) { + trigger(Event:Ack, in_msg.LineAddress); + } else if (in_msg.Type == DMAResponseType:DATA) { + trigger(Event:Data, in_msg.LineAddress); + } else { + error("Invalid response type"); + } + } + } + } + + action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") { + peek(dmaRequestQueue_in, SequencerMsg) { + enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) { + out_msg.PhysicalAddress := in_msg.PhysicalAddress; + out_msg.LineAddress := in_msg.LineAddress; + out_msg.Type := DMARequestType:READ; + out_msg.Requestor := machineID; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") { + peek(dmaRequestQueue_in, SequencerMsg) { + enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) { + out_msg.PhysicalAddress := in_msg.PhysicalAddress; + out_msg.LineAddress := in_msg.LineAddress; + out_msg.Type := DMARequestType:WRITE; + out_msg.Requestor := machineID; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(a_ackCallback, "a", desc="Notify dma controller that write request completed") { + peek (dmaResponseQueue_in, DMAResponseMsg) { + dma_sequencer.ackCallback(); + } + } + + action(d_dataCallback, "d", desc="Write data to dma sequencer") { + peek (dmaResponseQueue_in, DMAResponseMsg) { + dma_sequencer.dataCallback(in_msg.DataBlk); + } + } + + action(p_popRequestQueue, "p", desc="Pop request queue") { + dmaRequestQueue_in.dequeue(); + } + + action(p_popResponseQueue, "\p", desc="Pop request queue") { + dmaResponseQueue_in.dequeue(); + } + + transition(READY, ReadRequest, BUSY_RD) { + s_sendReadRequest; + p_popRequestQueue; + } + + transition(READY, WriteRequest, BUSY_WR) { + s_sendWriteRequest; + p_popRequestQueue; + } + + transition(BUSY_RD, Data, READY) { + d_dataCallback; + p_popResponseQueue; + } + + transition(BUSY_WR, Ack, READY) { + a_ackCallback; + p_popResponseQueue; + } +} diff --git a/src/mem/protocol/MOESI_hammer-msg.sm b/src/mem/protocol/MOESI_hammer-msg.sm index c9f1468198..5d8226eb6b 100644 --- a/src/mem/protocol/MOESI_hammer-msg.sm +++ b/src/mem/protocol/MOESI_hammer-msg.sm @@ -85,3 +85,35 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") { int Acks, desc="How many messages this counts as"; MessageSizeType MessageSize, desc="size category of the message"; } + +enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") { + READ, desc="Memory Read"; + WRITE, desc="Memory Write"; + NULL, desc="Invalid"; +} + +enumeration(DMAResponseType, desc="...", default="DMAResponseType_NULL") { + DATA, desc="DATA read"; + ACK, desc="ACK write"; + NULL, desc="Invalid"; +} + +structure(DMARequestMsg, desc="...", interface="NetworkMessage") { + DMARequestType Type, desc="Request type (read/write)"; + Address PhysicalAddress, desc="Physical address for this request"; + Address LineAddress, desc="Line address for this request"; + MachineID Requestor, desc="Node who initiated the request"; + NetDest Destination, desc="Destination"; + DataBlock DataBlk, desc="DataBlk attached to this request"; + int Len, desc="The length of the request"; + MessageSizeType MessageSize, desc="size category of the message"; +} + +structure(DMAResponseMsg, desc="...", interface="NetworkMessage") { + DMAResponseType Type, desc="Response type (DATA/ACK)"; + Address PhysicalAddress, desc="Physical address for this request"; + Address LineAddress, desc="Line address for this request"; + NetDest Destination, desc="Destination"; + DataBlock DataBlk, desc="DataBlk attached to this request"; + MessageSizeType MessageSize, desc="size category of the message"; +} diff --git a/src/mem/protocol/MOESI_hammer.slicc b/src/mem/protocol/MOESI_hammer.slicc index d49350e323..31ad47c2ef 100644 --- a/src/mem/protocol/MOESI_hammer.slicc +++ b/src/mem/protocol/MOESI_hammer.slicc @@ -1,4 +1,5 @@ MOESI_hammer-msg.sm MOESI_hammer-cache.sm MOESI_hammer-dir.sm +MOESI_hammer-dma.sm standard_1level_CMP-protocol.sm diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb index da7fa17c74..bb054ec4eb 100644 --- a/src/mem/ruby/config/defaults.rb +++ b/src/mem/ruby/config/defaults.rb @@ -178,6 +178,10 @@ class MOESI_hammer_DirectoryController < DirectoryController default_param :memory_controller_latency, Integer, 12 end +class MOESI_hammer_DMAController < DMAController + default_param :request_latency, Integer, 6 +end + class RubySystem # Random seed used by the simulation. If set to "rand", the seed From 8011e80725dfd2cba0cdc19917a0f740a1b40a06 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 153/160] ruby: The persistent table files from GEMS These files are need by the MOESI_CMP_token protocol. --- src/mem/ruby/system/PersistentTable.cc | 190 +++++++++++++++++++++++++ src/mem/ruby/system/PersistentTable.hh | 92 ++++++++++++ 2 files changed, 282 insertions(+) create mode 100644 src/mem/ruby/system/PersistentTable.cc create mode 100644 src/mem/ruby/system/PersistentTable.hh diff --git a/src/mem/ruby/system/PersistentTable.cc b/src/mem/ruby/system/PersistentTable.cc new file mode 100644 index 0000000000..1e056f6e53 --- /dev/null +++ b/src/mem/ruby/system/PersistentTable.cc @@ -0,0 +1,190 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PersistentTable.hh" +#include "NetDest.h" +#include "Map.h" +#include "Address.h" +#include "AbstractChip.h" +#include "util.h" + +// randomize so that handoffs are not locality-aware +// int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}; +// int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + + +class PersistentTableEntry { +public: + NetDest m_starving; + NetDest m_marked; + NetDest m_request_to_write; +}; + +PersistentTable::PersistentTable(AbstractChip* chip_ptr, int version) +{ + m_chip_ptr = chip_ptr; + m_map_ptr = new Map; + m_version = version; +} + +PersistentTable::~PersistentTable() +{ + delete m_map_ptr; + m_map_ptr = NULL; + m_chip_ptr = NULL; +} + +void PersistentTable::persistentRequestLock(const Address& address, MachineID locker, AccessType type) +{ + + // if (locker == m_chip_ptr->getID() ) + // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker << " requesting lock for " << address << endl; + + // MachineID locker = (MachineID) persistent_randomize[llocker]; + + assert(address == line_address(address)); + if (!m_map_ptr->exist(address)) { + // Allocate if not present + PersistentTableEntry entry; + entry.m_starving.add(locker); + if (type == AccessType_Write) { + entry.m_request_to_write.add(locker); + } + m_map_ptr->add(address, entry); + } else { + PersistentTableEntry& entry = m_map_ptr->lookup(address); + assert(!(entry.m_starving.isElement(locker))); // Make sure we're not already in the locked set + + entry.m_starving.add(locker); + if (type == AccessType_Write) { + entry.m_request_to_write.add(locker); + } + assert(entry.m_marked.isSubset(entry.m_starving)); + } +} + +void PersistentTable::persistentRequestUnlock(const Address& address, MachineID unlocker) +{ + // if (unlocker == m_chip_ptr->getID() ) + // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker << " requesting unlock for " << address << endl; + + // MachineID unlocker = (MachineID) persistent_randomize[uunlocker]; + + assert(address == line_address(address)); + assert(m_map_ptr->exist(address)); + PersistentTableEntry& entry = m_map_ptr->lookup(address); + assert(entry.m_starving.isElement(unlocker)); // Make sure we're in the locked set + assert(entry.m_marked.isSubset(entry.m_starving)); + entry.m_starving.remove(unlocker); + entry.m_marked.remove(unlocker); + entry.m_request_to_write.remove(unlocker); + assert(entry.m_marked.isSubset(entry.m_starving)); + + // Deallocate if empty + if (entry.m_starving.isEmpty()) { + assert(entry.m_marked.isEmpty()); + m_map_ptr->erase(address); + } +} + +bool PersistentTable::okToIssueStarving(const Address& address) const +{ + assert(address == line_address(address)); + if (!m_map_ptr->exist(address)) { + return true; // No entry present + } else if (m_map_ptr->lookup(address).m_starving.isElement( (MachineID) {MachineType_L1Cache, m_version})) { + return false; // We can't issue another lockdown until are previous unlock has occurred + } else { + return (m_map_ptr->lookup(address).m_marked.isEmpty()); + } +} + +MachineID PersistentTable::findSmallest(const Address& address) const +{ + assert(address == line_address(address)); + assert(m_map_ptr->exist(address)); + const PersistentTableEntry& entry = m_map_ptr->lookup(address); + // cout << "Node " << m_chip_ptr->getID() << " returning " << persistent_randomize[entry.m_starving.smallestElement()] << " for findSmallest(" << address << ")" << endl; + // return (MachineID) persistent_randomize[entry.m_starving.smallestElement()]; + return (MachineID) { MachineType_L1Cache, entry.m_starving.smallestElement() }; +} + +AccessType PersistentTable::typeOfSmallest(const Address& address) const +{ + assert(address == line_address(address)); + assert(m_map_ptr->exist(address)); + const PersistentTableEntry& entry = m_map_ptr->lookup(address); + if (entry.m_request_to_write.isElement((MachineID) {MachineType_L1Cache, entry.m_starving.smallestElement()})) { + return AccessType_Write; + } else { + return AccessType_Read; + } +} + +void PersistentTable::markEntries(const Address& address) +{ + assert(address == line_address(address)); + if (m_map_ptr->exist(address)) { + PersistentTableEntry& entry = m_map_ptr->lookup(address); + assert(entry.m_marked.isEmpty()); // None should be marked + entry.m_marked = entry.m_starving; // Mark all the nodes currently in the table + } +} + +bool PersistentTable::isLocked(const Address& address) const +{ + assert(address == line_address(address)); + // If an entry is present, it must be locked + return (m_map_ptr->exist(address)); +} + +int PersistentTable::countStarvingForAddress(const Address& address) const +{ + if (m_map_ptr->exist(address)) { + PersistentTableEntry& entry = m_map_ptr->lookup(address); + return (entry.m_starving.count()); + } + else { + return 0; + } +} + +int PersistentTable::countReadStarvingForAddress(const Address& address) const +{ + int count = 0; + if (m_map_ptr->exist(address)) { + PersistentTableEntry& entry = m_map_ptr->lookup(address); + return (entry.m_starving.count() - entry.m_request_to_write.count()); + } + else { + return 0; + } +} + + diff --git a/src/mem/ruby/system/PersistentTable.hh b/src/mem/ruby/system/PersistentTable.hh new file mode 100644 index 0000000000..ab000843d1 --- /dev/null +++ b/src/mem/ruby/system/PersistentTable.hh @@ -0,0 +1,92 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PersistentTable_H +#define PersistentTable_H + +#include "Global.h" +#include "MachineID.h" +#include "AccessType.h" + +class AbstractChip; + +template class Map; +class Address; +class PersistentTableEntry; + +class PersistentTable { +public: + // Constructors + PersistentTable(AbstractChip* chip_ptr, int version); + + // Destructor + ~PersistentTable(); + + // Public Methods + void persistentRequestLock(const Address& address, MachineID locker, AccessType type); + void persistentRequestUnlock(const Address& address, MachineID unlocker); + bool okToIssueStarving(const Address& address) const; + MachineID findSmallest(const Address& address) const; + AccessType typeOfSmallest(const Address& address) const; + void markEntries(const Address& address); + bool isLocked(const Address& addr) const; + int countStarvingForAddress(const Address& addr) const; + int countReadStarvingForAddress(const Address& addr) const; + + static void printConfig(ostream& out) {} + + void print(ostream& out) const; +private: + // Private Methods + + // Private copy constructor and assignment operator + PersistentTable(const PersistentTable& obj); + PersistentTable& operator=(const PersistentTable& obj); + + // Data Members (m_prefix) + Map* m_map_ptr; + AbstractChip* m_chip_ptr; + int m_version; +}; + +// Output operator declaration +ostream& operator<<(ostream& out, const PersistentTable& obj); + +// ******************* Definitions ******************* + +// Output operator definition +extern inline +ostream& operator<<(ostream& out, const PersistentTable& obj) +{ + obj.print(out); + out << flush; + return out; +} + +#endif //PersistentTable_H From c6330094fba3b67e5a6e422f8c7ad74b3c44eb17 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 154/160] m5: Added the default m5out directory to the hg ignore list --- .hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgignore b/.hgignore index f6a91e6e3c..5dd3b19129 100644 --- a/.hgignore +++ b/.hgignore @@ -7,3 +7,4 @@ cscope.out *.pyc *~ .*.swp +m5out From 20f872ed2a5dd7c1c08bbafc1cd5e82d6cc7444d Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 155/160] ruby: Added boolean to State Machine parameters * * * ruby: Removed primitive .hh includes --- src/mem/slicc/symbols/StateMachine.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index 8583ed46b0..0084388698 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -162,7 +162,7 @@ class StateMachine(Symbol): seen_types = set() for var in self.objects: - if var.type.ident not in seen_types: + if var.type.ident not in seen_types and not var.type.isPrimitive: code('#include "mem/protocol/${{var.type.c_ident}}.hh"') seen_types.add(var.type.ident) @@ -283,7 +283,7 @@ static int m_num_controllers; # include object classes seen_types = set() for var in self.objects: - if var.type.ident not in seen_types: + if var.type.ident not in seen_types and not var.type.isPrimitive: code('#include "mem/protocol/${{var.type.c_ident}}.hh"') seen_types.add(var.type.ident) @@ -339,8 +339,11 @@ void $c_ident::init(Network *net_ptr, const vector &argv) code('else if (argv[i] == "${{param.name}}")') if param.type_ast.type.ident == "int": code(' m_${{param.name}} = atoi(argv[i+1].c_str());') + elif param.type_ast.type.ident == "bool": + code(' m_${{param.name}} = string_to_bool(argv[i+1]);') else: - self.error("only int parameters are supported right now") + self.error("only int and bool parameters are "\ + "currently supported") code.dedent() code.dedent() code(''' From c9764b1ff1cfa3d1d82026e00cc5b4279c87cad0 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 156/160] ruby: added error message to isinstance check Added error message when a symbol is not an instance of a particular expected type. --- src/mem/slicc/symbols/SymbolTable.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mem/slicc/symbols/SymbolTable.py b/src/mem/slicc/symbols/SymbolTable.py index 17d7dfad3d..6b1bf13e63 100644 --- a/src/mem/slicc/symbols/SymbolTable.py +++ b/src/mem/slicc/symbols/SymbolTable.py @@ -72,7 +72,10 @@ class SymbolTable(object): continue if types is not None: - assert isinstance(symbol, types) + if not isinstance(symbol, types): + symbol.error("Symbol '%s' is not of types '%s'.", + symbol, + types) return symbol From dcac2ec24ce6f57ae7e3061a662c1657d486f6ec Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 157/160] ruby: removed the chip pointer from MessageBuffer The Chip object no longer exists and thus is removed from the MessageBuffer constructor. --- src/mem/ruby/buffers/MessageBuffer.cc | 3 +-- src/mem/ruby/buffers/MessageBuffer.hh | 6 +----- src/mem/ruby/network/simple/SimpleNetwork.cc | 4 ++-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc index eaa3965474..d157e2a94a 100644 --- a/src/mem/ruby/buffers/MessageBuffer.cc +++ b/src/mem/ruby/buffers/MessageBuffer.cc @@ -34,8 +34,7 @@ #include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/system/System.hh" -MessageBuffer::MessageBuffer(const Chip* chip_ptr, - const string &name) +MessageBuffer::MessageBuffer(const string &name) { m_msg_counter = 0; m_consumer_ptr = NULL; diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh index dfb66dfdf9..8440c33357 100644 --- a/src/mem/ruby/buffers/MessageBuffer.hh +++ b/src/mem/ruby/buffers/MessageBuffer.hh @@ -46,14 +46,10 @@ #include "mem/gems_common/PrioHeap.hh" #include "mem/gems_common/util.hh" -class Chip; - class MessageBuffer { public: // Constructors - // The chip_ptr is ignored, but could be used for extra debugging - MessageBuffer(const Chip* chip_ptr = NULL, - const string &name = ""); + MessageBuffer(const string &name = ""); // ~MessageBuffer() diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc index f6a217c917..adf7ee21e7 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.cc +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc @@ -87,9 +87,9 @@ void SimpleNetwork::init(const vector & argv) m_toNetQueues[node].setSize(m_virtual_networks); m_fromNetQueues[node].setSize(m_virtual_networks); for (int j = 0; j < m_virtual_networks; j++) { - m_toNetQueues[node][j] = new MessageBuffer(NULL, + m_toNetQueues[node][j] = new MessageBuffer( "toNet node "+int_to_string(node)+" j "+int_to_string(j)); - m_fromNetQueues[node][j] = new MessageBuffer(NULL, + m_fromNetQueues[node][j] = new MessageBuffer( "fromNet node "+int_to_string(node)+" j "+int_to_string(j)); } } From c6182199c54a874315a97338879d5bfaf3895a6f Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: [PATCH 158/160] m5: improvements to the ruby_fs.py file --- configs/example/ruby_fs.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/configs/example/ruby_fs.py b/configs/example/ruby_fs.py index d27eae596e..a4831f3bb7 100644 --- a/configs/example/ruby_fs.py +++ b/configs/example/ruby_fs.py @@ -71,8 +71,12 @@ parser.add_option("-o", "--options", default="", parser.add_option("-i", "--input", default="", help="Read stdin from a file.") parser.add_option("--output", default="", help="Redirect stdout to a file.") parser.add_option("--errout", default="", help="Redirect stderr to a file.") + +# ruby options parser.add_option("--ruby-debug", action="store_true") parser.add_option("--ruby-debug-file", default="", help="Ruby debug out file (stdout if blank)") +parser.add_option("--protocol", default="", help="Ruby protocol compiled into binary") + # ruby host memory experimentation parser.add_option("--cache_size", type="int") @@ -98,12 +102,17 @@ else: bm = [SysConfig()] # -# currently ruby fs only works in timing mode because ruby does not support -# atomic accesses by devices +# currently ruby fs only works in simple timing mode because ruby does not +# support atomic accesses by devices. Also ruby_fs currently assumes +# that is running a checkpoints that were created by ALPHA_FS under atomic +# mode. Since switch cpus are not defined in these checkpoints, we don't +# fast forward with the atomic cpu and instead set the FutureClass to None. +# Therefore the cpus resolve to the correct names and unserialize correctly. # assert(options.timing) - -(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(options) +class CPUClass(TimingSimpleCPU): pass +test_mem_mode = 'timing' +FutureClass = None CPUClass.clock = '1GHz' @@ -139,12 +148,22 @@ if options.map_levels: else: map_levels = 4 # 4 levels is the default +if options.protocol == "MOESI_hammer": + ruby_config_file = "MOESI_hammer-homogeneous.rb" +elif options.protocol == "MOESI_CMP_token": + ruby_config_file = "TwoLevel_SplitL1UnifiedL2.rb" +elif options.protocol == "MI_example": + ruby_config_file = "MI_example-homogeneous.rb" +else: + print "Error: unsupported ruby protocol" + sys.exit(1) + # # Currently, since ruby configuraiton is separate from m5, we need to manually # tell ruby that two dma ports are created by makeLinuxAlphaRubySystem(). # Eventually, this will be fix with a unified configuration system. # -rubymem = ruby_config.generate("MI_example-homogeneous.rb", +rubymem = ruby_config.generate(ruby_config_file, np, np, 128, From 5d8a669539a142ece820cf0c82722ea1c755d7cd Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:33 -0800 Subject: [PATCH 159/160] Resurrection of the CMP token protocol to GEM5 --- src/mem/protocol/MOESI_CMP_token-L1cache.sm | 351 ++++--- src/mem/protocol/MOESI_CMP_token-L2cache.sm | 174 ++-- src/mem/protocol/MOESI_CMP_token-dir.sm | 866 ++++++++++++++++-- src/mem/protocol/MOESI_CMP_token-dma.sm | 165 ++++ src/mem/protocol/MOESI_CMP_token-msg.sm | 54 +- src/mem/protocol/MOESI_CMP_token.slicc | 1 + src/mem/protocol/RubySlicc_Util.sm | 1 - src/mem/ruby/SConscript | 1 + src/mem/ruby/common/NetDest.cc | 5 +- src/mem/ruby/common/NetDest.hh | 2 +- src/mem/ruby/config/MOESI_CMP_token.rb | 92 ++ .../ruby/config/TwoLevel_SplitL1UnifiedL2.rb | 55 +- src/mem/ruby/config/cfg.rb | 1 - src/mem/ruby/config/defaults.rb | 27 + src/mem/ruby/system/PersistentTable.cc | 82 +- src/mem/ruby/system/PersistentTable.hh | 40 +- src/mem/ruby/system/SConscript | 1 + 17 files changed, 1580 insertions(+), 338 deletions(-) create mode 100644 src/mem/protocol/MOESI_CMP_token-dma.sm create mode 100644 src/mem/ruby/config/MOESI_CMP_token.rb diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index ab58c5c006..3fb4a88622 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -32,21 +32,32 @@ * */ -machine(L1Cache, "Token protocol") { +machine(L1Cache, "Token protocol") + : int l1_request_latency, + int l1_response_latency, + int l2_select_low_bit, + int l2_select_num_bits, + int N_tokens, + int retry_threshold, + int fixed_timeout_latency, + bool dynamic_timeout_enabled +{ // From this node's L1 cache TO the network - // a local L1 -> this L2 bank, currently ordered with directory forwarded requests - MessageBuffer requestFromL1Cache, network="To", virtual_network="0", ordered="false"; + // a local L1 -> this L2 bank - MessageBuffer responseFromL1Cache, network="To", virtual_network="2", ordered="false"; - MessageBuffer persistentFromL1Cache, network="To", virtual_network="3", ordered="true"; + MessageBuffer responseFromL1Cache, network="To", virtual_network="1", ordered="false"; + MessageBuffer persistentFromL1Cache, network="To", virtual_network="2", ordered="true"; + // a local L1 -> this L2 bank, currently ordered with directory forwarded requests + MessageBuffer requestFromL1Cache, network="To", virtual_network="4", ordered="false"; + // To this node's L1 cache FROM the network // a L2 bank -> this L1 - MessageBuffer requestToL1Cache, network="From", virtual_network="0", ordered="false"; + MessageBuffer responseToL1Cache, network="From", virtual_network="1", ordered="false"; + MessageBuffer persistentToL1Cache, network="From", virtual_network="2", ordered="true"; // a L2 bank -> this L1 - MessageBuffer responseToL1Cache, network="From", virtual_network="2", ordered="false"; - MessageBuffer persistentToL1Cache, network="From", virtual_network="3", ordered="true"; + MessageBuffer requestToL1Cache, network="From", virtual_network="4", ordered="false"; // STATES enumeration(State, desc="Cache states", default="L1Cache_State_I") { @@ -111,10 +122,6 @@ machine(L1Cache, "Token protocol") { // TYPES - int getRetryThreshold(); - int getFixedTimeoutLatency(); - bool getDynamicTimeoutEnabled(); - // CacheEntry structure(Entry, desc="...", interface="AbstractCacheEntry") { State CacheState, desc="cache state"; @@ -143,7 +150,7 @@ machine(L1Cache, "Token protocol") { external_type(CacheMemory) { bool cacheAvail(Address); Address cacheProbe(Address); - void allocate(Address); + void allocate(Address, Entry); void deallocate(Address); Entry lookup(Address); void changePermission(Address, AccessPermission); @@ -157,17 +164,28 @@ machine(L1Cache, "Token protocol") { bool isPresent(Address); } + external_type(PersistentTable) { + void persistentRequestLock(Address, MachineID, AccessType); + void persistentRequestUnlock(Address, MachineID); + bool okToIssueStarving(Address, MachineID); + MachineID findSmallest(Address); + AccessType typeOfSmallest(Address); + void markEntries(Address); + bool isLocked(Address); + int countStarvingForAddress(Address); + int countReadStarvingForAddress(Address); + } TBETable L1_TBEs, template_hack=""; - CacheMemory L1IcacheMemory, template_hack="", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1I"', abstract_chip_ptr="true"; - CacheMemory L1DcacheMemory, template_hack="", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1D"', abstract_chip_ptr="true"; + CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])'; + CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])'; MessageBuffer mandatoryQueue, ordered="false", abstract_chip_ptr="true"; - Sequencer sequencer, abstract_chip_ptr="true", constructor_hack="i"; + Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])'; bool starving, default="false"; - PersistentTable persistentTable, constructor_hack="i"; + PersistentTable persistentTable; TimerTable useTimerTable; TimerTable reissueTimerTable; @@ -175,11 +193,11 @@ machine(L1Cache, "Token protocol") { int outstandingPersistentRequests, default="0"; int averageLatencyHysteresis, default="(8)"; // Constant that provides hysteresis for calculated the estimated average - int averageLatencyCounter, default="(500 << (*m_L1Cache_averageLatencyHysteresis_vec[i]))"; + int averageLatencyCounter, default="(500 << (*m_L1Cache_averageLatencyHysteresis_ptr))"; int averageLatencyEstimate() { DEBUG_EXPR( (averageLatencyCounter >> averageLatencyHysteresis) ); - profile_average_latency_estimate( (averageLatencyCounter >> averageLatencyHysteresis) ); + //profile_average_latency_estimate( (averageLatencyCounter >> averageLatencyHysteresis) ); return averageLatencyCounter >> averageLatencyHysteresis; } @@ -366,30 +384,33 @@ machine(L1Cache, "Token protocol") { } } - GenericMachineType getNondirectHitMachType(Address addr, MachineID sender) { - if (machineIDToMachineType(sender) == MachineType:L1Cache) { - return GenericMachineType:L1Cache_wCC; // NOTE direct L1 hits should not call this - } else if (machineIDToMachineType(sender) == MachineType:L2Cache) { - if ( sender == (map_L1CacheMachId_to_L2Cache(addr,machineID))) { - return GenericMachineType:L2Cache; - } else { - return GenericMachineType:L2Cache_wCC; - } - } else { - return ConvertMachToGenericMach(machineIDToMachineType(sender)); - } - } +// GenericMachineType getNondirectHitMachType(Address addr, MachineID sender) { +// if (machineIDToMachineType(sender) == MachineType:L1Cache) { +// return GenericMachineType:L1Cache_wCC; // NOTE direct L1 hits should not call this +// } else if (machineIDToMachineType(sender) == MachineType:L2Cache) { +// +// if (sender == (mapAddressToRange(addr, +// MachineType:L2Cache, +// l2_select_low_bit, +// l2_select_num_bits))) { +// +// return GenericMachineType:L2Cache; +// } else { +// return GenericMachineType:L2Cache_wCC; +// } +// } else { +// return ConvertMachToGenericMach(machineIDToMachineType(sender)); +// } +// } - bool okToIssueStarving(Address addr) { - return persistentTable.okToIssueStarving(addr); + bool okToIssueStarving(Address addr, MachineID machinID) { + return persistentTable.okToIssueStarving(addr, machineID); } void markPersistentEntries(Address addr) { persistentTable.markEntries(addr); } - MessageBuffer triggerQueue, ordered="false", random="false"; - // ** OUT_PORTS ** out_port(persistentNetwork_out, PersistentMsg, persistentFromL1Cache); out_port(requestNetwork_out, RequestMsg, requestFromL1Cache); @@ -507,7 +528,11 @@ machine(L1Cache, "Token protocol") { // Mark TBE flag if response received off-chip. Use this to update average latency estimate if ( in_msg.SenderMachine == MachineType:L2Cache ) { - if (in_msg.Sender == map_L1CacheMachId_to_L2Cache(in_msg.Address, machineID)) { + if (in_msg.Sender == mapAddressToRange(in_msg.Address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)) { + // came from an off-chip L2 cache if (L1_TBEs.isPresent(in_msg.Address)) { // L1_TBEs[in_msg.Address].ExternalResponse := true; @@ -523,15 +548,15 @@ machine(L1Cache, "Token protocol") { // profile_memory_response( in_msg.Address); } } else if ( in_msg.SenderMachine == MachineType:L1Cache) { - if (isLocalProcessor(machineID, in_msg.Sender) == false) { - if (L1_TBEs.isPresent(in_msg.Address)) { + //if (isLocalProcessor(machineID, in_msg.Sender) == false) { + //if (L1_TBEs.isPresent(in_msg.Address)) { // L1_TBEs[in_msg.Address].ExternalResponse := true; // profile_offchipL1_response(in_msg.Address ); - } - } - else { + //} + //} + //else { // profile_onchipL1_response(in_msg.Address ); - } + //} } else { error("unexpected SenderMachine"); } @@ -570,42 +595,42 @@ machine(L1Cache, "Token protocol") { // ** INSTRUCTION ACCESS *** // Check to see if it is in the OTHER L1 - if (L1DcacheMemory.isTagPresent(in_msg.Address)) { + if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) { // The block is in the wrong L1, try to write it to the L2 - trigger(Event:L1_Replacement, in_msg.Address); + trigger(Event:L1_Replacement, in_msg.LineAddress); } - if (L1IcacheMemory.isTagPresent(in_msg.Address)) { + if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) { // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { - if (L1IcacheMemory.cacheAvail(in_msg.Address)) { + if (L1IcacheMemory.cacheAvail(in_msg.LineAddress)) { // L1 does't have the line, but we have space for it in the L1 - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { // No room in the L1, so we need to make room - trigger(Event:L1_Replacement, L1IcacheMemory.cacheProbe(in_msg.Address)); + trigger(Event:L1_Replacement, L1IcacheMemory.cacheProbe(in_msg.LineAddress)); } } } else { // *** DATA ACCESS *** // Check to see if it is in the OTHER L1 - if (L1IcacheMemory.isTagPresent(in_msg.Address)) { + if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) { // The block is in the wrong L1, try to write it to the L2 - trigger(Event:L1_Replacement, in_msg.Address); + trigger(Event:L1_Replacement, in_msg.LineAddress); } - if (L1DcacheMemory.isTagPresent(in_msg.Address)) { + if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) { // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { - if (L1DcacheMemory.cacheAvail(in_msg.Address)) { + if (L1DcacheMemory.cacheAvail(in_msg.LineAddress)) { // L1 does't have the line, but we have space for it in the L1 - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address); + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { // No room in the L1, so we need to make room - trigger(Event:L1_Replacement, L1DcacheMemory.cacheProbe(in_msg.Address)); + trigger(Event:L1_Replacement, L1DcacheMemory.cacheProbe(in_msg.LineAddress)); } } } @@ -618,19 +643,31 @@ machine(L1Cache, "Token protocol") { action(a_issueReadRequest, "a", desc="Issue GETS") { if (L1_TBEs[address].IssueCount == 0) { // Update outstanding requests - profile_outstanding_request(outstandingRequests); + //profile_outstanding_request(outstandingRequests); outstandingRequests := outstandingRequests + 1; } - if (L1_TBEs[address].IssueCount >= getRetryThreshold() ) { + if (L1_TBEs[address].IssueCount >= retry_threshold) { // Issue a persistent request if possible - if (okToIssueStarving(address) && (starving == false)) { - enqueue(persistentNetwork_out, PersistentMsg, latency="L1_REQUEST_LATENCY") { + if (okToIssueStarving(address, machineID) && (starving == false)) { + enqueue(persistentNetwork_out, PersistentMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := PersistentRequestType:GETS_PERSISTENT; out_msg.Requestor := machineID; out_msg.Destination.broadcast(MachineType:L1Cache); - out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := L1_TBEs[address].Prefetch; @@ -640,11 +677,11 @@ machine(L1Cache, "Token protocol") { starving := true; if (L1_TBEs[address].IssueCount == 0) { - profile_persistent_prediction(address, L1_TBEs[address].AccessType); + //profile_persistent_prediction(address, L1_TBEs[address].AccessType); } // Update outstanding requests - profile_outstanding_persistent_request(outstandingPersistentRequests); + //profile_outstanding_persistent_request(outstandingPersistentRequests); outstandingPersistentRequests := outstandingPersistentRequests + 1; // Increment IssueCount @@ -666,11 +703,16 @@ machine(L1Cache, "Token protocol") { } } else { // Make a normal request - enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETS; out_msg.Requestor := machineID; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.RetryNum := L1_TBEs[address].IssueCount; if (L1_TBEs[address].IssueCount == 0) { out_msg.MessageSize := MessageSizeType:Request_Control; @@ -682,11 +724,18 @@ machine(L1Cache, "Token protocol") { } // send to other local L1s, with local bit set - enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETS; out_msg.Requestor := machineID; - out_msg.Destination := getOtherLocalL1IDs(machineID); + + // + // Since only one chip, assuming all L1 caches are local + // + //out_msg.Destination := getOtherLocalL1IDs(machineID); + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.remove(machineID); + out_msg.RetryNum := L1_TBEs[address].IssueCount; out_msg.isLocal := true; if (L1_TBEs[address].IssueCount == 0) { @@ -703,10 +752,10 @@ machine(L1Cache, "Token protocol") { // Set a wakeup timer - if (getDynamicTimeoutEnabled()) { + if (dynamic_timeout_enabled) { reissueTimerTable.set(address, 1.25 * averageLatencyEstimate()); } else { - reissueTimerTable.set(address, getFixedTimeoutLatency()); + reissueTimerTable.set(address, fixed_timeout_latency); } } @@ -716,20 +765,32 @@ machine(L1Cache, "Token protocol") { if (L1_TBEs[address].IssueCount == 0) { // Update outstanding requests - profile_outstanding_request(outstandingRequests); + //profile_outstanding_request(outstandingRequests); outstandingRequests := outstandingRequests + 1; } - if (L1_TBEs[address].IssueCount >= getRetryThreshold() ) { + if (L1_TBEs[address].IssueCount >= retry_threshold) { // Issue a persistent request if possible - if ( okToIssueStarving(address) && (starving == false)) { - enqueue(persistentNetwork_out, PersistentMsg, latency="L1_REQUEST_LATENCY") { + if ( okToIssueStarving(address, machineID) && (starving == false)) { + enqueue(persistentNetwork_out, PersistentMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := PersistentRequestType:GETX_PERSISTENT; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L1Cache; out_msg.Destination.broadcast(MachineType:L1Cache); - out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := L1_TBEs[address].Prefetch; @@ -739,11 +800,11 @@ machine(L1Cache, "Token protocol") { starving := true; // Update outstanding requests - profile_outstanding_persistent_request(outstandingPersistentRequests); + //profile_outstanding_persistent_request(outstandingPersistentRequests); outstandingPersistentRequests := outstandingPersistentRequests + 1; if (L1_TBEs[address].IssueCount == 0) { - profile_persistent_prediction(address, L1_TBEs[address].AccessType); + //profile_persistent_prediction(address, L1_TBEs[address].AccessType); } // Increment IssueCount @@ -766,12 +827,17 @@ machine(L1Cache, "Token protocol") { } else { // Make a normal request - enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L1Cache; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.RetryNum := L1_TBEs[address].IssueCount; if (L1_TBEs[address].IssueCount == 0) { @@ -784,12 +850,19 @@ machine(L1Cache, "Token protocol") { } // send to other local L1s too - enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") { + enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; out_msg.isLocal := true; - out_msg.Destination := getOtherLocalL1IDs(machineID); + + // + // Since only one chip, assuming all L1 caches are local + // + //out_msg.Destination := getOtherLocalL1IDs(machineID); + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.remove(machineID); + out_msg.RetryNum := L1_TBEs[address].IssueCount; if (L1_TBEs[address].IssueCount == 0) { out_msg.MessageSize := MessageSizeType:Request_Control; @@ -807,10 +880,10 @@ machine(L1Cache, "Token protocol") { DEBUG_EXPR(L1_TBEs[address].IssueCount); // Set a wakeup timer - if (getDynamicTimeoutEnabled()) { + if (dynamic_timeout_enabled) { reissueTimerTable.set(address, 1.25 * averageLatencyEstimate()); } else { - reissueTimerTable.set(address, getFixedTimeoutLatency()); + reissueTimerTable.set(address, fixed_timeout_latency); } } } @@ -818,7 +891,7 @@ machine(L1Cache, "Token protocol") { action(bb_bounceResponse, "\b", desc="Bounce tokens and data to memory") { peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -833,11 +906,16 @@ machine(L1Cache, "Token protocol") { } action(c_ownedReplacement, "c", desc="Issue writeback") { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Tokens := getCacheEntry(address).Tokens; out_msg.DataBlk := getCacheEntry(address).DataBlk; out_msg.Dirty := getCacheEntry(address).Dirty; @@ -853,11 +931,16 @@ machine(L1Cache, "Token protocol") { // don't send writeback if replacing block with no tokens if (getCacheEntry(address).Tokens != 0) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Tokens := getCacheEntry(address).Tokens; out_msg.DataBlk := getCacheEntry(address).DataBlk; // assert(getCacheEntry(address).Dirty == false); @@ -879,7 +962,7 @@ machine(L1Cache, "Token protocol") { action(d_sendDataWithToken, "d", desc="Send data and a token from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; @@ -902,14 +985,14 @@ machine(L1Cache, "Token protocol") { action(d_sendDataWithNTokenIfAvail, "\dd", desc="Send data and a token from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - if (getCacheEntry(address).Tokens > N_tokens()) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + if (getCacheEntry(address).Tokens > N_tokens) { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; out_msg.Destination.add(in_msg.Requestor); - out_msg.Tokens := N_tokens(); + out_msg.Tokens := N_tokens; out_msg.DataBlk := getCacheEntry(address).DataBlk; // out_msg.Dirty := getCacheEntry(address).Dirty; out_msg.Dirty := false; @@ -919,10 +1002,10 @@ machine(L1Cache, "Token protocol") { out_msg.MessageSize := MessageSizeType:Response_Data; } } - getCacheEntry(address).Tokens := getCacheEntry(address).Tokens - N_tokens(); + getCacheEntry(address).Tokens := getCacheEntry(address).Tokens - N_tokens; } else if (getCacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; @@ -946,7 +1029,7 @@ machine(L1Cache, "Token protocol") { action(dd_sendDataWithAllTokens, "\d", desc="Send data and all tokens from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -969,7 +1052,7 @@ machine(L1Cache, "Token protocol") { action(e_sendAckWithCollectedTokens, "e", desc="Send ack with the tokens we've collected thus far.") { // assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself if (getCacheEntry(address).Tokens > 0) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -986,7 +1069,7 @@ machine(L1Cache, "Token protocol") { action(ee_sendDataWithAllTokens, "\e", desc="Send data and all tokens from cache to starver") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getCacheEntry(address).Tokens > 0); - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -1005,23 +1088,23 @@ machine(L1Cache, "Token protocol") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getCacheEntry(address).Tokens > 0); if (getCacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; out_msg.Destination.add(persistentTable.findSmallest(address)); assert(getCacheEntry(address).Tokens >= 1); - if (getCacheEntry(address).Tokens > N_tokens()) { - out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens(); + if (getCacheEntry(address).Tokens > N_tokens) { + out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens; } else { out_msg.Tokens := getCacheEntry(address).Tokens - 1; } out_msg.MessageSize := MessageSizeType:Response_Control; } } - if (getCacheEntry(address).Tokens > N_tokens()) { - getCacheEntry(address).Tokens := N_tokens(); + if (getCacheEntry(address).Tokens > N_tokens) { + getCacheEntry(address).Tokens := N_tokens; } else { getCacheEntry(address).Tokens := 1; } @@ -1031,15 +1114,15 @@ machine(L1Cache, "Token protocol") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getCacheEntry(address).Tokens > 0); if (getCacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; out_msg.Destination.add(persistentTable.findSmallest(address)); assert(getCacheEntry(address).Tokens >= 1); - if (getCacheEntry(address).Tokens > N_tokens()) { - out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens(); + if (getCacheEntry(address).Tokens > N_tokens) { + out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens; } else { out_msg.Tokens := getCacheEntry(address).Tokens - 1; } @@ -1047,8 +1130,8 @@ machine(L1Cache, "Token protocol") { out_msg.Dirty := getCacheEntry(address).Dirty; out_msg.MessageSize := MessageSizeType:Response_Data; } - if (getCacheEntry(address).Tokens > N_tokens()) { - getCacheEntry(address).Tokens := N_tokens(); + if (getCacheEntry(address).Tokens > N_tokens) { + getCacheEntry(address).Tokens := N_tokens; } else { getCacheEntry(address).Tokens := 1; } @@ -1061,7 +1144,7 @@ machine(L1Cache, "Token protocol") { peek(responseNetwork_in, ResponseMsg) { // assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself // FIXME, should use a 3rd vnet in some cases - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -1079,7 +1162,8 @@ machine(L1Cache, "Token protocol") { action(h_load_hit, "h", desc="Notify sequencer the load completed.") { DEBUG_EXPR(address); DEBUG_EXPR(getCacheEntry(address).DataBlk); - sequencer.readCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No); + //sequencer.readCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No); + sequencer.readCallback(address, getCacheEntry(address).DataBlk); } action(x_external_load_hit, "x", desc="Notify sequencer the load completed.") { @@ -1087,14 +1171,16 @@ machine(L1Cache, "Token protocol") { DEBUG_EXPR(getCacheEntry(address).DataBlk); peek(responseNetwork_in, ResponseMsg) { - sequencer.readCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No); + //sequencer.readCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No); + sequencer.readCallback(address, getCacheEntry(address).DataBlk); } } action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") { DEBUG_EXPR(address); DEBUG_EXPR(getCacheEntry(address).DataBlk); - sequencer.writeCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No); + //sequencer.writeCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No); + sequencer.writeCallback(address, getCacheEntry(address).DataBlk); getCacheEntry(address).Dirty := true; DEBUG_EXPR(getCacheEntry(address).DataBlk); } @@ -1103,7 +1189,8 @@ machine(L1Cache, "Token protocol") { DEBUG_EXPR(address); DEBUG_EXPR(getCacheEntry(address).DataBlk); peek(responseNetwork_in, ResponseMsg) { - sequencer.writeCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No); + //sequencer.writeCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No); + sequencer.writeCallback(address, getCacheEntry(address).DataBlk); } getCacheEntry(address).Dirty := true; DEBUG_EXPR(getCacheEntry(address).DataBlk); @@ -1133,8 +1220,6 @@ machine(L1Cache, "Token protocol") { useTimerTable.unset(address); } - - action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") { mandatoryQueue_in.dequeue(); } @@ -1156,14 +1241,19 @@ machine(L1Cache, "Token protocol") { } action(p_informL2AboutTokenLoss, "p", desc="Inform L2 about loss of all tokens") { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:INV; out_msg.Tokens := 0; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L1Cache; out_msg.DestMachine := MachineType:L2Cache; - out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.MessageSize := MessageSizeType:Response_Control; } } @@ -1189,13 +1279,25 @@ machine(L1Cache, "Token protocol") { if (L1_TBEs[address].WentPersistent) { // assert(starving == true); outstandingRequests := outstandingRequests - 1; - enqueue(persistentNetwork_out, PersistentMsg, latency="L1_REQUEST_LATENCY") { + enqueue(persistentNetwork_out, PersistentMsg, latency = l1_request_latency) { out_msg.Address := address; out_msg.Type := PersistentRequestType:DEACTIVATE_PERSISTENT; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L1Cache; out_msg.Destination.broadcast(MachineType:L1Cache); - out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Persistent_Control; } @@ -1217,14 +1319,14 @@ machine(L1Cache, "Token protocol") { // profile_token_retry(address, L1_TBEs[address].AccessType, 1); //} - profile_token_retry(address, L1_TBEs[address].AccessType, L1_TBEs[address].IssueCount); + //profile_token_retry(address, L1_TBEs[address].AccessType, L1_TBEs[address].IssueCount); L1_TBEs.deallocate(address); } action(t_sendAckWithCollectedTokens, "t", desc="Send ack with the tokens we've collected thus far.") { if (getCacheEntry(address).Tokens > 0) { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -1259,13 +1361,13 @@ machine(L1Cache, "Token protocol") { action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") { if (L1DcacheMemory.isTagPresent(address) == false) { - L1DcacheMemory.allocate(address); + L1DcacheMemory.allocate(address, new Entry); } } action(pp_allocateL1ICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B.") { if (L1IcacheMemory.isTagPresent(address) == false) { - L1IcacheMemory.allocate(address); + L1IcacheMemory.allocate(address, new Entry); } } @@ -1281,11 +1383,6 @@ machine(L1Cache, "Token protocol") { } } - - action(z_stall, "z", desc="Stall") { - - } - action(zz_recycleMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") { mandatoryQueue_in.recycle(); } diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm index 0a58ed5cf7..9a5c400f25 100644 --- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm @@ -32,20 +32,33 @@ * */ -machine(L2Cache, "Token protocol") { +machine(L2Cache, "Token protocol") + : int l2_request_latency, + int l2_response_latency, + int N_tokens, + bool filtering_enabled +{ // L2 BANK QUEUES // From local bank of L2 cache TO the network - MessageBuffer L1RequestFromL2Cache, network="To", virtual_network="0", ordered="false"; // this L2 bank -> a local L1 - MessageBuffer GlobalRequestFromL2Cache, network="To", virtual_network="1", ordered="false"; // this L2 bank -> mod-directory - MessageBuffer responseFromL2Cache, network="To", virtual_network="2", ordered="false"; // this L2 bank -> a local L1 || mod-directory + + // this L2 bank -> a local L1 || mod-directory + MessageBuffer responseFromL2Cache, network="To", virtual_network="1", ordered="false"; + // this L2 bank -> mod-directory + MessageBuffer GlobalRequestFromL2Cache, network="To", virtual_network="3", ordered="false"; + // this L2 bank -> a local L1 + MessageBuffer L1RequestFromL2Cache, network="To", virtual_network="4", ordered="false"; // FROM the network to this local bank of L2 cache - MessageBuffer L1RequestToL2Cache, network="From", virtual_network="0", ordered="false"; // a local L1 -> this L2 bank - MessageBuffer GlobalRequestToL2Cache, network="From", virtual_network="1", ordered="false"; // mod-directory -> this L2 bank - MessageBuffer responseToL2Cache, network="From", virtual_network="2", ordered="false"; // a local L1 || mod-directory -> this L2 bank - MessageBuffer persistentToL2Cache, network="From", virtual_network="3", ordered="true"; + + // a local L1 || mod-directory -> this L2 bank + MessageBuffer responseToL2Cache, network="From", virtual_network="1", ordered="false"; + MessageBuffer persistentToL2Cache, network="From", virtual_network="2", ordered="true"; + // mod-directory -> this L2 bank + MessageBuffer GlobalRequestToL2Cache, network="From", virtual_network="3", ordered="false"; + // a local L1 -> this L2 bank + MessageBuffer L1RequestToL2Cache, network="From", virtual_network="4", ordered="false"; // STATES enumeration(State, desc="L2 Cache states", default="L2Cache_State_I") { @@ -107,8 +120,6 @@ machine(L2Cache, "Token protocol") { DataBlock DataBlk, desc="data for the block"; } - - structure(DirEntry, desc="...") { Set Sharers, desc="Set of the internal processors that want the block in shared state"; bool exclusive, default="false", desc="if local exclusive is likely"; @@ -117,7 +128,7 @@ machine(L2Cache, "Token protocol") { external_type(CacheMemory) { bool cacheAvail(Address); Address cacheProbe(Address); - void allocate(Address); + void allocate(Address, Entry); void deallocate(Address); Entry lookup(Address); void changePermission(Address, AccessPermission); @@ -132,19 +143,28 @@ machine(L2Cache, "Token protocol") { bool isTagPresent(Address); } + external_type(PersistentTable) { + void persistentRequestLock(Address, MachineID, AccessType); + void persistentRequestUnlock(Address, MachineID); + MachineID findSmallest(Address); + AccessType typeOfSmallest(Address); + void markEntries(Address); + bool isLocked(Address); + int countStarvingForAddress(Address); + int countReadStarvingForAddress(Address); + } - CacheMemory L2cacheMemory, template_hack="", constructor_hack='L2_CACHE_NUM_SETS_BITS,L2_CACHE_ASSOC,MachineType_L2Cache,int_to_string(i)+"_L2"'; + CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["cache"])'; - PersistentTable persistentTable, constructor_hack="i"; + PersistentTable persistentTable; PerfectCacheMemory localDirectory, template_hack=""; - - bool getFilteringEnabled(); - Entry getL2CacheEntry(Address addr), return_by_ref="yes" { if (L2cacheMemory.isTagPresent(addr)) { return L2cacheMemory[addr]; } + assert(false); + return L2cacheMemory[addr]; } int getTokens(Address addr) { @@ -465,15 +485,21 @@ machine(L2Cache, "Token protocol") { // if this is a retry or no local sharers, broadcast normally // if (in_msg.RetryNum > 0 || (in_msg.Type == CoherenceRequestType:GETX && exclusiveExists(in_msg.Address) == false) || (in_msg.Type == CoherenceRequestType:GETS && sharersExist(in_msg.Address) == false)) { - enqueue(globalRequestNetwork_out, RequestMsg, latency="L2_REQUEST_LATENCY") { + enqueue(globalRequestNetwork_out, RequestMsg, latency=l2_request_latency) { out_msg.Address := in_msg.Address; out_msg.Type := in_msg.Type; out_msg.Requestor := in_msg.Requestor; out_msg.RequestorMachine := in_msg.RequestorMachine; - //out_msg.Destination.broadcast(MachineType:L2Cache); out_msg.RetryNum := in_msg.RetryNum; - out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); - out_msg.Destination.remove(map_L1CacheMachId_to_L2Cache(address, in_msg.Requestor)); + + // + // If a statically shared L2 cache, then no other L2 caches can + // store the block + // + //out_msg.Destination.broadcast(MachineType:L2Cache); + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + //out_msg.Destination.remove(map_L1CacheMachId_to_L2Cache(address, in_msg.Requestor)); + out_msg.Destination.add(map_Address_to_Directory(address)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.AccessMode := in_msg.AccessMode; @@ -489,7 +515,7 @@ machine(L2Cache, "Token protocol") { action(bb_bounceResponse, "\b", desc="Bounce tokens and data to memory") { peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -505,7 +531,7 @@ machine(L2Cache, "Token protocol") { action(c_cleanReplacement, "c", desc="Issue clean writeback") { if (getL2CacheEntry(address).Tokens > 0) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -519,7 +545,7 @@ machine(L2Cache, "Token protocol") { } action(cc_dirtyReplacement, "\c", desc="Issue dirty writeback") { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; @@ -541,22 +567,22 @@ machine(L2Cache, "Token protocol") { action(d_sendDataWithTokens, "d", desc="Send data and a token from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - if (getL2CacheEntry(address).Tokens > N_tokens()) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + if (getL2CacheEntry(address).Tokens > N_tokens) { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; out_msg.Destination.add(in_msg.Requestor); - out_msg.Tokens := N_tokens(); + out_msg.Tokens := N_tokens; out_msg.DataBlk := getL2CacheEntry(address).DataBlk; out_msg.Dirty := false; out_msg.MessageSize := MessageSizeType:Response_Data; } - getL2CacheEntry(address).Tokens := getL2CacheEntry(address).Tokens - N_tokens(); + getL2CacheEntry(address).Tokens := getL2CacheEntry(address).Tokens - N_tokens; } else { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; @@ -574,7 +600,7 @@ machine(L2Cache, "Token protocol") { action(dd_sendDataWithAllTokens, "\d", desc="Send data and all tokens from cache to requestor") { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -592,7 +618,7 @@ machine(L2Cache, "Token protocol") { action(e_sendAckWithCollectedTokens, "e", desc="Send ack with the tokens we've collected thus far.") { if (getL2CacheEntry(address).Tokens > 0) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -607,7 +633,7 @@ machine(L2Cache, "Token protocol") { } action(ee_sendDataWithAllTokens, "\e", desc="Send data and all tokens from cache to starver") { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -626,7 +652,7 @@ machine(L2Cache, "Token protocol") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getL2CacheEntry(address).Tokens > 0); if (getL2CacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -644,7 +670,7 @@ machine(L2Cache, "Token protocol") { //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself assert(getL2CacheEntry(address).Tokens > 0); if (getL2CacheEntry(address).Tokens > 1) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -666,7 +692,7 @@ machine(L2Cache, "Token protocol") { // assert(persistentTable.isLocked(address)); peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet in some cases - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -684,7 +710,7 @@ machine(L2Cache, "Token protocol") { //assert(persistentTable.isLocked(address)); peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet in some cases - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; if (in_msg.Type == CoherenceResponseType:WB_SHARED_DATA) { out_msg.Type := CoherenceResponseType:DATA_SHARED; @@ -706,7 +732,7 @@ machine(L2Cache, "Token protocol") { // assert(persistentTable.isLocked(address)); peek(responseNetwork_in, ResponseMsg) { // FIXME, should use a 3rd vnet in some cases - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -729,24 +755,31 @@ machine(L2Cache, "Token protocol") { action(j_forwardTransientRequestToLocalSharers, "j", desc="Forward external transient request to local sharers") { peek(requestNetwork_in, RequestMsg) { - if (getFilteringEnabled() == true && in_msg.RetryNum == 0 && sharersExist(in_msg.Address) == false) { - profile_filter_action(1); + if (filtering_enabled == true && in_msg.RetryNum == 0 && sharersExist(in_msg.Address) == false) { + //profile_filter_action(1); DEBUG_EXPR("filtered message"); DEBUG_EXPR(in_msg.RetryNum); } else { - enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) { + enqueue(localRequestNetwork_out, RequestMsg, latency=l2_response_latency ) { out_msg.Address := in_msg.Address; out_msg.Requestor := in_msg.Requestor; out_msg.RequestorMachine := in_msg.RequestorMachine; - out_msg.Destination := getLocalL1IDs(machineID); + + // + // Currently assuming only one chip so all L1s are local + // + //out_msg.Destination := getLocalL1IDs(machineID); + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.remove(in_msg.Requestor); + out_msg.Type := in_msg.Type; out_msg.isLocal := false; out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.AccessMode := in_msg.AccessMode; out_msg.Prefetch := in_msg.Prefetch; } - profile_filter_action(0); + //profile_filter_action(0); } } } @@ -756,7 +789,7 @@ machine(L2Cache, "Token protocol") { peek(L1requestNetwork_in, RequestMsg) { assert(getL2CacheEntry(address).Tokens > 0); //enqueue(responseIntraChipL2Network_out, ResponseMsg, latency="L2_to_L1_RESPONSE_LATENCY") { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_SHARED; out_msg.Sender := machineID; @@ -774,7 +807,7 @@ machine(L2Cache, "Token protocol") { action(k_dataOwnerFromL2CacheToL1Requestor, "\k", desc="Send data and a token from cache to L1 requestor") { peek(L1requestNetwork_in, RequestMsg) { assert(getL2CacheEntry(address).Tokens > 0); - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -793,7 +826,7 @@ machine(L2Cache, "Token protocol") { peek(L1requestNetwork_in, RequestMsg) { // assert(getL2CacheEntry(address).Tokens == max_tokens()); //enqueue(responseIntraChipL2Network_out, ResponseMsg, latency="L2_to_L1_RESPONSE_LATENCY") { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -840,12 +873,13 @@ machine(L2Cache, "Token protocol") { } action(r_markNewSharer, "r", desc="Mark the new local sharer from local request message") { - peek(L1requestNetwork_in, RequestMsg) { - if (in_msg.Type == CoherenceRequestType:GETX) { - setNewWriter(in_msg.Address, machineIDToNodeID(in_msg.Requestor)); - } else if (in_msg.Type == CoherenceRequestType:GETS) { - addNewSharer(in_msg.Address, machineIDToNodeID(in_msg.Requestor)); + if (machineIDToMachineType(in_msg.Requestor) == MachineType:L1Cache) { + if (in_msg.Type == CoherenceRequestType:GETX) { + setNewWriter(in_msg.Address, machineIDToNodeID(in_msg.Requestor)); + } else if (in_msg.Type == CoherenceRequestType:GETS) { + addNewSharer(in_msg.Address, machineIDToNodeID(in_msg.Requestor)); + } } } } @@ -854,16 +888,19 @@ machine(L2Cache, "Token protocol") { clearExclusiveBitIfExists(address); } - action( r_setMRU, "\rr", desc="manually set the MRU bit for cache line" ) { - if(isCacheTagPresent(address)) { - L2cacheMemory.setMRU(address); + action(r_setMRU, "\rr", desc="manually set the MRU bit for cache line" ) { + peek(L1requestNetwork_in, RequestMsg) { + if ((machineIDToMachineType(in_msg.Requestor) == MachineType:L1Cache) && + (isCacheTagPresent(address))) { + L2cacheMemory.setMRU(address); + } } } action(t_sendAckWithCollectedTokens, "t", desc="Send ack with the tokens we've collected thus far.") { if (getL2CacheEntry(address).Tokens > 0) { peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -881,7 +918,7 @@ machine(L2Cache, "Token protocol") { action(tt_sendLocalAckWithCollectedTokens, "tt", desc="Send ack with the tokens we've collected thus far.") { if (getL2CacheEntry(address).Tokens > 0) { peek(L1requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) { out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -906,19 +943,19 @@ machine(L2Cache, "Token protocol") { } action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") { - L2cacheMemory.allocate(address); + L2cacheMemory.allocate(address, new Entry); } action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") { L2cacheMemory.deallocate(address); } - action(uu_profileMiss, "\u", desc="Profile the demand miss") { - peek(L1requestNetwork_in, RequestMsg) { + //action(uu_profileMiss, "\u", desc="Profile the demand miss") { + // peek(L1requestNetwork_in, RequestMsg) { // AccessModeType not implemented //profile_L2Cache_miss(convertToGenericType(in_msg.Type), in_msg.AccessMode, MessageSizeTypeToInt(in_msg.MessageSize), in_msg.Prefetch, machineIDToNodeID(in_msg.Requestor)); - } - } + // } + //} action(w_assertIncomingDataAndCacheDataMatch, "w", desc="Assert that the incoming data and the data in the cache match") { @@ -927,11 +964,6 @@ machine(L2Cache, "Token protocol") { } } - action(z_stall, "z", desc="Stall") { - } - - - //***************************************************** // TRANSITIONS @@ -961,7 +993,7 @@ machine(L2Cache, "Token protocol") { transition(NP, {L1_GETS, L1_GETX}) { a_broadcastLocalRequest; r_markNewSharer; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1012,7 +1044,7 @@ machine(L2Cache, "Token protocol") { a_broadcastLocalRequest; tt_sendLocalAckWithCollectedTokens; // send any tokens we have collected r_markNewSharer; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1020,7 +1052,7 @@ machine(L2Cache, "Token protocol") { a_broadcastLocalRequest; tt_sendLocalAckWithCollectedTokens; // send any tokens we have collected r_markNewSharer; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1181,7 +1213,7 @@ machine(L2Cache, "Token protocol") { tt_sendLocalAckWithCollectedTokens; r_markNewSharer; r_setMRU; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1294,7 +1326,7 @@ machine(L2Cache, "Token protocol") { k_dataAndAllTokensFromL2CacheToL1Requestor; r_markNewSharer; r_setMRU; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1382,7 +1414,7 @@ machine(L2Cache, "Token protocol") { transition(I_L, {L1_GETX, L1_GETS}) { a_broadcastLocalRequest; r_markNewSharer; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } @@ -1391,7 +1423,7 @@ machine(L2Cache, "Token protocol") { tt_sendLocalAckWithCollectedTokens; r_markNewSharer; r_setMRU; - uu_profileMiss; + //uu_profileMiss; o_popL1RequestQueue; } diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm index 1592fd1237..7925a8fe0d 100644 --- a/src/mem/protocol/MOESI_CMP_token-dir.sm +++ b/src/mem/protocol/MOESI_CMP_token-dir.sm @@ -32,14 +32,23 @@ */ -machine(Directory, "Token protocol") { +machine(Directory, "Token protocol") + : int directory_latency, + int l2_select_low_bit, + int l2_select_num_bits, + bool distributed_persistent, + int fixed_timeout_latency +{ - MessageBuffer requestFromDir, network="To", virtual_network="1", ordered="false"; - MessageBuffer responseFromDir, network="To", virtual_network="2", ordered="false"; + MessageBuffer dmaResponseFromDir, network="To", virtual_network="0", ordered="true"; + MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false"; + MessageBuffer persistentFromDir, network="To", virtual_network="2", ordered="true"; + MessageBuffer requestFromDir, network="To", virtual_network="4", ordered="false"; - MessageBuffer persistentToDir, network="From", virtual_network="3", ordered="true"; - MessageBuffer requestToDir, network="From", virtual_network="1", ordered="false"; - MessageBuffer responseToDir, network="From", virtual_network="2", ordered="false"; + MessageBuffer responseToDir, network="From", virtual_network="1", ordered="false"; + MessageBuffer persistentToDir, network="From", virtual_network="2", ordered="true"; + MessageBuffer requestToDir, network="From", virtual_network="3", ordered="false"; + MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true"; // STATES enumeration(State, desc="Directory states", default="Directory_State_O") { @@ -47,6 +56,24 @@ machine(Directory, "Token protocol") { O, desc="Owner"; NO, desc="Not Owner"; L, desc="Locked"; + + // Memory wait states - can block all messages including persistent requests + O_W, desc="transitioning to Owner, waiting for memory write"; + L_W, desc="transitioning to Locked, waiting for memory read"; + DR_L_W, desc="transitioning to Locked underneath a DMA read, waiting for memory data"; + NO_W, desc="transitioning to Not Owner, waiting for memory read"; + O_DW_W, desc="transitioning to Owner, waiting for memory before DMA ack"; + O_DR_W, desc="transitioning to Owner, waiting for memory before DMA data"; + + // DMA request transient states - must respond to persistent requests + O_DW, desc="issued GETX for DMA write, waiting for all tokens"; + NO_DW, desc="issued GETX for DMA write, waiting for all tokens"; + NO_DR, desc="issued GETS for DMA read, waiting for data"; + + // DMA request in progress - competing with a CPU persistent request + DW_L, desc="issued GETX for DMA write, CPU persistent request must complete first"; + DR_L, desc="issued GETS for DMA read, CPU persistent request must complete first"; + } // Events @@ -55,9 +82,23 @@ machine(Directory, "Token protocol") { GETS, desc="A GETS arrives"; Lockdown, desc="A lockdown request arrives"; Unlockdown, desc="An un-lockdown request arrives"; + Own_Lock_or_Unlock, desc="own lock or unlock"; Data_Owner, desc="Data arrive"; + Data_All_Tokens, desc="Data and all tokens"; Ack_Owner, desc="Owner token arrived without data because it was clean"; + Ack_Owner_All_Tokens, desc="All tokens including owner arrived without data because it was clean"; Tokens, desc="Tokens arrive"; + Ack_All_Tokens, desc="All_Tokens arrive"; + Request_Timeout, desc="A DMA request has timed out"; + + // Memory Controller + Memory_Data, desc="Fetched data from memory arrives"; + Memory_Ack, desc="Writeback Ack from memory arrives"; + + // DMA requests + DMA_READ, desc="A DMA Read memory request"; + DMA_WRITE, desc="A DMA Write memory request"; + DMA_WRITE_All_Tokens, desc="A DMA Write memory request, directory has all tokens"; } // TYPES @@ -73,7 +114,7 @@ machine(Directory, "Token protocol") { // is 'soft state' that does not need to be correct (as long as // you're eventually willing to resort to broadcast.) - Set Owner, desc="Probable Owner of the line. More accurately, the set of processors who need to see a GetS or GetO. We use a Set for convenience, but only one bit is set at a time."; + Set Owner, desc="Probable Owner of the line. More accurately, the set of processors who need to see a GetS or GetO. We use a Set for convenience, but only one bit is set at a time."; Set Sharers, desc="Probable sharers of the line. More accurately, the set of processors who need to see a GetX"; } @@ -82,23 +123,70 @@ machine(Directory, "Token protocol") { bool isPresent(Address); } + external_type(MemoryControl, inport="yes", outport="yes") { + + } + + external_type(PersistentTable) { + void persistentRequestLock(Address, MachineID, AccessType); + void persistentRequestUnlock(Address, MachineID); + bool okToIssueStarving(Address, MachineID); + MachineID findSmallest(Address); + AccessType typeOfSmallest(Address); + void markEntries(Address); + bool isLocked(Address); + int countStarvingForAddress(Address); + int countReadStarvingForAddress(Address); + } + + // TBE entries for DMA requests + structure(TBE, desc="TBE entries for outstanding DMA requests") { + Address PhysicalAddress, desc="physical address"; + State TBEState, desc="Transient State"; + DataBlock DmaDataBlk, desc="DMA Data to be written. Partial blocks need to merged with system memory"; + DataBlock DataBlk, desc="The current view of system memory"; + int Len, desc="..."; + MachineID DmaRequestor, desc="DMA requestor"; + bool WentPersistent, desc="Did the DMA request require a persistent request"; + } + + external_type(TBETable) { + TBE lookup(Address); + void allocate(Address); + void deallocate(Address); + bool isPresent(Address); + } // ** OBJECTS ** - DirectoryMemory directory, constructor_hack="i"; + DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])'; - PersistentTable persistentTable, constructor_hack="i"; + MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])'; + + PersistentTable persistentTable; + TimerTable reissueTimerTable; + + TBETable TBEs, template_hack=""; + + bool starving, default="false"; State getState(Address addr) { - return directory[addr].DirectoryState; + if (TBEs.isPresent(addr)) { + return TBEs[addr].TBEState; + } else { + return directory[addr].DirectoryState; + } } void setState(Address addr, State state) { + if (TBEs.isPresent(addr)) { + TBEs[addr].TBEState := state; + } directory[addr].DirectoryState := state; if (state == State:L) { assert(directory[addr].Tokens == 0); - } + } // We have one or zero owners assert((directory[addr].Owner.count() == 0) || (directory[addr].Owner.count() == 1)); @@ -112,19 +200,90 @@ machine(Directory, "Token protocol") { // assert(directory[addr].Tokens >= (max_tokens() / 2)); // Only mostly true; this might not always hold } } + + bool okToIssueStarving(Address addr, MachineID machinID) { + return persistentTable.okToIssueStarving(addr, machineID); + } + + void markPersistentEntries(Address addr) { + persistentTable.markEntries(addr); + } // ** OUT_PORTS ** out_port(responseNetwork_out, ResponseMsg, responseFromDir); + out_port(persistentNetwork_out, PersistentMsg, persistentFromDir); out_port(requestNetwork_out, RequestMsg, requestFromDir); + out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir); + + // + // Memory buffer for memory controller to DIMM communication + // + out_port(memQueue_out, MemoryMsg, memBuffer); // ** IN_PORTS ** + + // off-chip memory request/response is done + in_port(memQueue_in, MemoryMsg, memBuffer) { + if (memQueue_in.isReady()) { + peek(memQueue_in, MemoryMsg) { + if (in_msg.Type == MemoryRequestType:MEMORY_READ) { + trigger(Event:Memory_Data, in_msg.Address); + } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) { + trigger(Event:Memory_Ack, in_msg.Address); + } else { + DEBUG_EXPR(in_msg.Type); + error("Invalid message"); + } + } + } + } + + // Reissue Timer + in_port(reissueTimerTable_in, Address, reissueTimerTable) { + if (reissueTimerTable_in.isReady()) { + trigger(Event:Request_Timeout, reissueTimerTable.readyAddress()); + } + } + + in_port(responseNetwork_in, ResponseMsg, responseToDir) { + if (responseNetwork_in.isReady()) { + peek(responseNetwork_in, ResponseMsg) { + assert(in_msg.Destination.isElement(machineID)); + if (directory[in_msg.Address].Tokens + in_msg.Tokens == max_tokens()) { + if ((in_msg.Type == CoherenceResponseType:DATA_OWNER) || + (in_msg.Type == CoherenceResponseType:DATA_SHARED)) { + trigger(Event:Data_All_Tokens, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) { + trigger(Event:Ack_Owner_All_Tokens, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK) { + trigger(Event:Ack_All_Tokens, in_msg.Address); + } else { + DEBUG_EXPR(in_msg.Type); + error("Invalid message"); + } + } else { + if (in_msg.Type == CoherenceResponseType:DATA_OWNER) { + trigger(Event:Data_Owner, in_msg.Address); + } else if ((in_msg.Type == CoherenceResponseType:ACK) || + (in_msg.Type == CoherenceResponseType:DATA_SHARED)) { + trigger(Event:Tokens, in_msg.Address); + } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) { + trigger(Event:Ack_Owner, in_msg.Address); + } else { + DEBUG_EXPR(in_msg.Type); + error("Invalid message"); + } + } + } + } + } in_port(persistentNetwork_in, PersistentMsg, persistentToDir) { if (persistentNetwork_in.isReady()) { peek(persistentNetwork_in, PersistentMsg) { assert(in_msg.Destination.isElement(machineID)); - if (distributedPersistentEnabled()) { + if (distributed_persistent) { // Apply the lockdown or unlockdown message to the table if (in_msg.Type == PersistentRequestType:GETX_PERSISTENT) { persistentTable.persistentRequestLock(in_msg.Address, in_msg.Requestor, AccessType:Write); @@ -173,19 +332,18 @@ machine(Directory, "Token protocol") { } } - in_port(responseNetwork_in, ResponseMsg, responseToDir) { - if (responseNetwork_in.isReady()) { - peek(responseNetwork_in, ResponseMsg) { - assert(in_msg.Destination.isElement(machineID)); - if (in_msg.Type == CoherenceResponseType:DATA_OWNER) { - trigger(Event:Data_Owner, in_msg.Address); - } else if ((in_msg.Type == CoherenceResponseType:ACK) || - (in_msg.Type == CoherenceResponseType:DATA_SHARED)) { - trigger(Event:Tokens, in_msg.Address); - } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) { - trigger(Event:Ack_Owner, in_msg.Address); + in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) { + if (dmaRequestQueue_in.isReady()) { + peek(dmaRequestQueue_in, DMARequestMsg) { + if (in_msg.Type == DMARequestType:READ) { + trigger(Event:DMA_READ, in_msg.LineAddress); + } else if (in_msg.Type == DMARequestType:WRITE) { + if (directory[in_msg.LineAddress].Tokens == max_tokens()) { + trigger(Event:DMA_WRITE_All_Tokens, in_msg.LineAddress); + } else { + trigger(Event:DMA_WRITE, in_msg.LineAddress); + } } else { - DEBUG_EXPR(in_msg.Type); error("Invalid message"); } } @@ -199,7 +357,7 @@ machine(Directory, "Token protocol") { if (directory[address].Tokens > 0) { peek(requestNetwork_in, RequestMsg) { // enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_CACHE_LATENCY") {// FIXME? - enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_LATENCY") {// FIXME? + enqueue(responseNetwork_out, ResponseMsg, latency=directory_latency) {// FIXME? out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -213,11 +371,151 @@ machine(Directory, "Token protocol") { } } + action(px_tryIssuingPersistentGETXRequest, "px", desc="...") { + if (okToIssueStarving(address, machineID) && (starving == false)) { + enqueue(persistentNetwork_out, PersistentMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := PersistentRequestType:GETX_PERSISTENT; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + out_msg.Destination.broadcast(MachineType:L1Cache); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Persistent_Control; + out_msg.Prefetch := PrefetchBit:No; + out_msg.AccessMode := AccessModeType:SupervisorMode; + } + markPersistentEntries(address); + starving := true; + + TBEs[address].WentPersistent := true; + + // Do not schedule a wakeup, a persistent requests will always complete + } else { + + // We'd like to issue a persistent request, but are not allowed + // to issue a P.R. right now. This, we do not increment the + // IssueCount. + + // Set a wakeup timer + reissueTimerTable.set(address, 10); + } + } + + action(bw_broadcastWrite, "bw", desc="Broadcast GETX if we need tokens") { + peek(dmaRequestQueue_in, DMARequestMsg) { + // + // Assser that we only send message if we don't already have all the tokens + // + assert(directory[address].Tokens != max_tokens()); + enqueue(requestNetwork_out, RequestMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETX; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + + // + // Since only one chip, assuming all L1 caches are local + // + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.RetryNum := 0; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Prefetch := PrefetchBit:No; + out_msg.AccessMode := AccessModeType:SupervisorMode; + } + } + } + + action(ps_tryIssuingPersistentGETSRequest, "ps", desc="...") { + if (okToIssueStarving(address, machineID) && (starving == false)) { + enqueue(persistentNetwork_out, PersistentMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := PersistentRequestType:GETS_PERSISTENT; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + out_msg.Destination.broadcast(MachineType:L1Cache); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Persistent_Control; + out_msg.Prefetch := PrefetchBit:No; + out_msg.AccessMode := AccessModeType:SupervisorMode; + } + markPersistentEntries(address); + starving := true; + + TBEs[address].WentPersistent := true; + + // Do not schedule a wakeup, a persistent requests will always complete + } else { + + // We'd like to issue a persistent request, but are not allowed + // to issue a P.R. right now. This, we do not increment the + // IssueCount. + + // Set a wakeup timer + reissueTimerTable.set(address, 10); + } + } + + action(br_broadcastRead, "br", desc="Broadcast GETS for data") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(requestNetwork_out, RequestMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := CoherenceRequestType:GETS; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + + // + // Since only one chip, assuming all L1 caches are local + // + out_msg.Destination.broadcast(MachineType:L1Cache); + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.RetryNum := 0; + out_msg.MessageSize := MessageSizeType:Request_Control; + out_msg.Prefetch := PrefetchBit:No; + out_msg.AccessMode := AccessModeType:SupervisorMode; + } + } + } + action(aa_sendTokensToStarver, "\a", desc="Send tokens to starver") { // Only send a message if we have tokens to send if (directory[address].Tokens > 0) { // enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_CACHE_LATENCY") {// FIXME? - enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_LATENCY") {// FIXME? + enqueue(responseNetwork_out, ResponseMsg, latency=directory_latency) {// FIXME? out_msg.Address := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; @@ -230,14 +528,14 @@ machine(Directory, "Token protocol") { } } - action(d_sendDataWithAllTokens, "d", desc="Send data and tokens to requestor") { - peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { + action(d_sendMemoryDataWithAllTokens, "d", desc="Send data and tokens to requestor") { + peek(memQueue_in, MemoryMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:Directory; - out_msg.Destination.add(in_msg.Requestor); + out_msg.Destination.add(in_msg.OriginalRequestorMachId); assert(directory[address].Tokens > 0); out_msg.Tokens := directory[in_msg.Address].Tokens; out_msg.DataBlk := directory[in_msg.Address].DataBlk; @@ -249,21 +547,140 @@ machine(Directory, "Token protocol") { } action(dd_sendDataWithAllTokensToStarver, "\d", desc="Send data and tokens to starver") { - enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") { - out_msg.Address := address; - out_msg.Type := CoherenceResponseType:DATA_OWNER; - out_msg.Sender := machineID; - out_msg.SenderMachine := MachineType:Directory; - out_msg.Destination.add(persistentTable.findSmallest(address)); - assert(directory[address].Tokens > 0); - out_msg.Tokens := directory[address].Tokens; - out_msg.DataBlk := directory[address].DataBlk; - out_msg.Dirty := false; - out_msg.MessageSize := MessageSizeType:Response_Data; + peek(memQueue_in, MemoryMsg) { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := CoherenceResponseType:DATA_OWNER; + out_msg.Sender := machineID; + out_msg.SenderMachine := MachineType:Directory; + out_msg.Destination.add(persistentTable.findSmallest(address)); + assert(directory[address].Tokens > 0); + out_msg.Tokens := directory[address].Tokens; + out_msg.DataBlk := directory[address].DataBlk; + out_msg.Dirty := false; + out_msg.MessageSize := MessageSizeType:Response_Data; + } } directory[address].Tokens := 0; } + action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { + peek(requestNetwork_in, RequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := in_msg.Requestor; + out_msg.MessageSize := in_msg.MessageSize; + out_msg.DataBlk := directory[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + } + + action(fd_memoryDma, "fd", desc="Queue off-chip fetch request") { + peek(dmaRequestQueue_in, DMARequestMsg) { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_READ; + out_msg.Sender := machineID; + out_msg.OriginalRequestorMachId := in_msg.Requestor; + out_msg.MessageSize := in_msg.MessageSize; + out_msg.DataBlk := directory[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + } + + action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + DEBUG_EXPR(out_msg); + } + } + + action(ld_queueMemoryDmaWriteFromTbe, "ld", desc="Write DMA data to memory") { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + // first, initialize the data blk to the current version of system memory + out_msg.DataBlk := TBEs[address].DataBlk; + // then add the dma write data + out_msg.DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + DEBUG_EXPR(out_msg); + } + } + + action(lr_queueMemoryDmaReadWriteback, "lr", desc="Write DMA data from read to memory") { + enqueue(memQueue_out, MemoryMsg, latency="1") { + out_msg.Address := address; + out_msg.Type := MemoryRequestType:MEMORY_WB; + // first, initialize the data blk to the current version of system memory + out_msg.DataBlk := TBEs[address].DataBlk; + DEBUG_EXPR(out_msg); + } + } + + action(vd_allocateDmaRequestInTBE, "vd", desc="Record Data in TBE") { + peek(dmaRequestQueue_in, DMARequestMsg) { + TBEs.allocate(address); + TBEs[address].DmaDataBlk := in_msg.DataBlk; + TBEs[address].PhysicalAddress := in_msg.PhysicalAddress; + TBEs[address].Len := in_msg.Len; + TBEs[address].DmaRequestor := in_msg.Requestor; + TBEs[address].WentPersistent := false; + } + } + + action(s_deallocateTBE, "s", desc="Deallocate TBE") { + + if (TBEs[address].WentPersistent) { + assert(starving == true); + + enqueue(persistentNetwork_out, PersistentMsg, latency = "1") { + out_msg.Address := address; + out_msg.Type := PersistentRequestType:DEACTIVATE_PERSISTENT; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:Directory; + out_msg.Destination.broadcast(MachineType:L1Cache); + + // + // Currently the configuration system limits the system to only one + // chip. Therefore, if we assume one shared L2 cache, then only one + // pertinent L2 cache exist. + // + //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); + + out_msg.Destination.add(mapAddressToRange(address, + MachineType:L2Cache, + l2_select_low_bit, + l2_select_num_bits)); + + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Persistent_Control; + } + starving := false; + } + + TBEs.deallocate(address); + } + + action(rd_recordDataInTbe, "rd", desc="Record data in TBE") { + peek(responseNetwork_in, ResponseMsg) { + TBEs[address].DataBlk := in_msg.DataBlk; + } + } + + action(cd_writeCleanDataToTbe, "cd", desc="Write clean memory data to TBE") { + TBEs[address].DataBlk := directory[address].DataBlk; + } + + action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") { + directory[address].DataBlk := TBEs[address].DataBlk; + directory[address].DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + } + action(f_incrementTokens, "f", desc="Increment the number of tokens we're tracking") { peek(responseNetwork_in, ResponseMsg) { assert(in_msg.Tokens >= 1); @@ -275,14 +692,34 @@ machine(Directory, "Token protocol") { requestNetwork_in.dequeue(); } + action(z_recycleRequest, "z", desc="Recycle the request queue") { + requestNetwork_in.recycle(); + } + action(k_popIncomingResponseQueue, "k", desc="Pop incoming response queue") { responseNetwork_in.dequeue(); } + action(kz_recycleResponse, "kz", desc="Recycle incoming response queue") { + responseNetwork_in.recycle(); + } + action(l_popIncomingPersistentQueue, "l", desc="Pop incoming persistent queue") { persistentNetwork_in.dequeue(); } + action(p_popDmaRequestQueue, "pd", desc="pop dma request queue") { + dmaRequestQueue_in.dequeue(); + } + + action(y_recycleDmaRequestQueue, "y", desc="recycle dma request queue") { + dmaRequestQueue_in.recycle(); + } + + action(l_popMemQueue, "q", desc="Pop off-chip request queue") { + memQueue_in.dequeue(); + } + action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") { peek(responseNetwork_in, ResponseMsg) { directory[in_msg.Address].DataBlk := in_msg.DataBlk; @@ -291,18 +728,15 @@ machine(Directory, "Token protocol") { } } - action(n_checkIncomingMsg, "n", desc="Check incoming token message") { + action(n_checkData, "n", desc="Check incoming clean data message") { peek(responseNetwork_in, ResponseMsg) { - assert(in_msg.Type == CoherenceResponseType:ACK_OWNER); - assert(in_msg.Dirty == false); - assert(in_msg.MessageSize == MessageSizeType:Writeback_Control); assert(directory[in_msg.Address].DataBlk == in_msg.DataBlk); } } action(r_bounceResponse, "r", desc="Bounce response to starving processor") { peek(responseNetwork_in, ResponseMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; @@ -316,7 +750,20 @@ machine(Directory, "Token protocol") { } } - action(s_bounceDatalessOwnerToken, "s", desc="Bounce clean owner token to starving processor") { + action(st_scheduleTimeout, "st", desc="Schedule Timeout") { + // + // currently only support a fixed timeout latency + // + reissueTimerTable.set(address, fixed_timeout_latency); + } + + action(ut_unsetReissueTimer, "ut", desc="Unset reissue timer.") { + if (reissueTimerTable.isSet(address)) { + reissueTimerTable.unset(address); + } + } + + action(bd_bounceDatalessOwnerToken, "bd", desc="Bounce clean owner token to starving processor") { peek(responseNetwork_in, ResponseMsg) { assert(in_msg.Type == CoherenceResponseType:ACK_OWNER); assert(in_msg.Dirty == false); @@ -331,7 +778,7 @@ machine(Directory, "Token protocol") { // Bounce the message, but "re-associate" the data and the owner // token. In essence we're converting an ACK_OWNER message to a // DATA_OWNER message, keeping the number of tokens the same. - enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") { + enqueue(responseNetwork_out, ResponseMsg, latency="1") { out_msg.Address := address; out_msg.Type := CoherenceResponseType:DATA_OWNER; out_msg.Sender := machineID; @@ -346,53 +793,212 @@ machine(Directory, "Token protocol") { } } + action(da_sendDmaAck, "da", desc="Send Ack to DMA controller") { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:ACK; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + + action(dm_sendMemoryDataToDma, "dm", desc="Send Data to DMA controller from memory") { + peek(memQueue_in, MemoryMsg) { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:DATA; + // + // we send the entire data block and rely on the dma controller to + // split it up if need be + // + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } + + action(dd_sendDmaData, "dd", desc="Send Data to DMA controller") { + peek(responseNetwork_in, ResponseMsg) { + enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") { + out_msg.PhysicalAddress := address; + out_msg.LineAddress := address; + out_msg.Type := DMAResponseType:DATA; + // + // we send the entire data block and rely on the dma controller to + // split it up if need be + // + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.MessageSize := MessageSizeType:Response_Data; + } + } + } // TRANSITIONS - // Trans. from O - transition(O, GETX, NO) { - d_sendDataWithAllTokens; + // + // Trans. from base state O + // the directory has valid data + // + transition(O, GETX, NO_W) { + qf_queueMemoryFetchRequest; j_popIncomingRequestQueue; } - transition(O, GETS, NO) { - d_sendDataWithAllTokens; + transition(O, DMA_WRITE, O_DW) { + vd_allocateDmaRequestInTBE; + bw_broadcastWrite; + st_scheduleTimeout; + p_popDmaRequestQueue; + } + + transition(O, DMA_WRITE_All_Tokens, O_DW_W) { + vd_allocateDmaRequestInTBE; + cd_writeCleanDataToTbe; + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWriteFromTbe; + p_popDmaRequestQueue; + } + + transition(O, GETS, NO_W) { + qf_queueMemoryFetchRequest; j_popIncomingRequestQueue; } - transition(O, Lockdown, L) { - dd_sendDataWithAllTokensToStarver; + transition(O, DMA_READ, O_DR_W) { + vd_allocateDmaRequestInTBE; + fd_memoryDma; + st_scheduleTimeout; + p_popDmaRequestQueue; + } + + transition(O, Lockdown, L_W) { + qf_queueMemoryFetchRequest; l_popIncomingPersistentQueue; } - transition(O, Tokens) { + transition(O, {Tokens, Ack_All_Tokens}) { f_incrementTokens; k_popIncomingResponseQueue; } + transition(O, {Data_Owner, Data_All_Tokens}) { + n_checkData; + f_incrementTokens; + k_popIncomingResponseQueue; + } + + // + // transitioning to Owner, waiting for memory before DMA ack + // All other events should recycle/stall + // + transition(O_DR_W, Memory_Data, O) { + dm_sendMemoryDataToDma; + ut_unsetReissueTimer; + s_deallocateTBE; + l_popMemQueue; + } + + // + // issued GETX for DMA write, waiting for all tokens + // + transition(O_DW, Tokens) { + f_incrementTokens; + k_popIncomingResponseQueue; + } + + transition(O_DW, Data_Owner) { + f_incrementTokens; + rd_recordDataInTbe; + k_popIncomingResponseQueue; + } + + transition(O_DW, Ack_Owner) { + f_incrementTokens; + cd_writeCleanDataToTbe; + k_popIncomingResponseQueue; + } + + transition(O_DW, Lockdown, DW_L) { + l_popIncomingPersistentQueue; + } + + transition({NO_DW, O_DW}, Data_All_Tokens, O_DW_W) { + f_incrementTokens; + rd_recordDataInTbe; + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWriteFromTbe; + ut_unsetReissueTimer; + k_popIncomingResponseQueue; + } + + transition(O_DW, Ack_All_Tokens, O_DW_W) { + f_incrementTokens; + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWriteFromTbe; + ut_unsetReissueTimer; + k_popIncomingResponseQueue; + } + + transition(O_DW, Ack_Owner_All_Tokens, O_DW_W) { + f_incrementTokens; + cd_writeCleanDataToTbe; + dwt_writeDmaDataFromTBE; + ld_queueMemoryDmaWriteFromTbe; + ut_unsetReissueTimer; + k_popIncomingResponseQueue; + } + + transition(O_DW_W, Memory_Ack, O) { + da_sendDmaAck; + s_deallocateTBE; + l_popMemQueue; + } + + // // Trans. from NO + // The direcotry does not have valid data, but may have some tokens + // transition(NO, GETX) { a_sendTokens; j_popIncomingRequestQueue; } + transition(NO, DMA_WRITE, NO_DW) { + vd_allocateDmaRequestInTBE; + bw_broadcastWrite; + st_scheduleTimeout; + p_popDmaRequestQueue; + } + transition(NO, GETS) { j_popIncomingRequestQueue; } + transition(NO, DMA_READ, NO_DR) { + vd_allocateDmaRequestInTBE; + br_broadcastRead; + st_scheduleTimeout; + p_popDmaRequestQueue; + } + transition(NO, Lockdown, L) { aa_sendTokensToStarver; l_popIncomingPersistentQueue; } - transition(NO, Data_Owner, O) { + transition(NO, {Data_Owner, Data_All_Tokens}, O_W) { m_writeDataToMemory; f_incrementTokens; + lq_queueMemoryWbRequest; k_popIncomingResponseQueue; } - transition(NO, Ack_Owner, O) { - n_checkIncomingMsg; + transition(NO, {Ack_Owner, Ack_Owner_All_Tokens}, O) { + n_checkData; f_incrementTokens; k_popIncomingResponseQueue; } @@ -402,34 +1008,156 @@ machine(Directory, "Token protocol") { k_popIncomingResponseQueue; } - // Trans. from L - transition(L, {GETX, GETS}) { - j_popIncomingRequestQueue; + transition(NO_W, Memory_Data, NO) { + d_sendMemoryDataWithAllTokens; + l_popMemQueue; } - transition(L, Lockdown) { + // Trans. from NO_DW + transition(NO_DW, Request_Timeout) { + ut_unsetReissueTimer; + px_tryIssuingPersistentGETXRequest; + } + + transition(NO_DW, Lockdown, DW_L) { + aa_sendTokensToStarver; l_popIncomingPersistentQueue; } - // we could change this to write the data to memory and send it cleanly - transition(L, Data_Owner) { + // Note: NO_DW, Data_All_Tokens transition is combined with O_DW + // Note: NO_DW should not receive the action Ack_All_Tokens because the + // directory does not have valid data + + transition(NO_DW, Data_Owner, O_DW) { + f_incrementTokens; + rd_recordDataInTbe; + lq_queueMemoryWbRequest; + k_popIncomingResponseQueue; + } + + transition({NO_DW, NO_DR}, Tokens) { + f_incrementTokens; + k_popIncomingResponseQueue; + } + + // Trans. from NO_DR + transition(NO_DR, Request_Timeout) { + ut_unsetReissueTimer; + ps_tryIssuingPersistentGETSRequest; + } + + transition(NO_DR, Lockdown, DR_L) { + aa_sendTokensToStarver; + l_popIncomingPersistentQueue; + } + + transition(NO_DR, {Data_Owner, Data_All_Tokens}, O_W) { + m_writeDataToMemory; + f_incrementTokens; + dd_sendDmaData; + lr_queueMemoryDmaReadWriteback; + ut_unsetReissueTimer; + s_deallocateTBE; + k_popIncomingResponseQueue; + } + + // Trans. from L + transition({L, DW_L, DR_L}, {GETX, GETS}) { + j_popIncomingRequestQueue; + } + + transition({L, DW_L, DR_L, L_W, DR_L_W}, Lockdown) { + l_popIncomingPersistentQueue; + } + + // + // Received data for lockdown blocks + // For blocks with outstanding dma requests to them + // ...we could change this to write the data to memory and send it cleanly + // ...we could also proactively complete our DMA requests + // However, to keep my mind from spinning out-of-control, we won't for now :) + // + transition({DW_L, DR_L, L}, {Data_Owner, Data_All_Tokens}) { r_bounceResponse; k_popIncomingResponseQueue; } - transition(L, Tokens) { + transition({DW_L, DR_L, L}, Tokens) { r_bounceResponse; k_popIncomingResponseQueue; } - transition(L, Ack_Owner) { - s_bounceDatalessOwnerToken; + transition({DW_L, DR_L, L}, {Ack_Owner_All_Tokens, Ack_Owner}) { + bd_bounceDatalessOwnerToken; k_popIncomingResponseQueue; } - transition(L, Unlockdown, NO) { l_popIncomingPersistentQueue; } + transition(L_W, Memory_Data, L) { + dd_sendDataWithAllTokensToStarver; + l_popMemQueue; + } + + transition(DR_L_W, Memory_Data, DR_L) { + dd_sendDataWithAllTokensToStarver; + l_popMemQueue; + } + + transition(DW_L, {Unlockdown, Own_Lock_or_Unlock}, NO_DW) { + l_popIncomingPersistentQueue; + } + + transition(DR_L_W, {Unlockdown, Own_Lock_or_Unlock}, O_DR_W) { + l_popIncomingPersistentQueue; + } + + transition({DW_L, DR_L_W}, Request_Timeout) { + ut_unsetReissueTimer; + px_tryIssuingPersistentGETXRequest; + } + + transition(DR_L, {Unlockdown, Own_Lock_or_Unlock}, NO_DR) { + l_popIncomingPersistentQueue; + } + + transition(DR_L, Request_Timeout) { + ut_unsetReissueTimer; + ps_tryIssuingPersistentGETSRequest; + } + + transition(O_W, Memory_Ack, O) { + l_popMemQueue; + } + + transition({O, NO, L, O_DW, NO_DW, NO_DR}, Own_Lock_or_Unlock) { + l_popIncomingPersistentQueue; + } + + // Blocked states + transition({NO_W, O_W, L_W, DR_L_W, O_DW_W, O_DR_W, O_DW, NO_DW, NO_DR}, {GETX, GETS}) { + z_recycleRequest; + } + + transition({NO_W, O_W, L_W, DR_L_W, O_DW_W, O_DR_W, O_DW, NO_DW, NO_DR, L, DW_L, DR_L}, {DMA_READ, DMA_WRITE}) { + y_recycleDmaRequestQueue; + } + + transition({NO_W, O_W, L_W, DR_L_W, O_DW_W, O_DR_W}, {Data_Owner, Ack_Owner, Tokens}) { + kz_recycleResponse; + } + + transition({NO_W, O_W}, Lockdown, L_W) { + l_popIncomingPersistentQueue; + } + + transition(O_DR_W, Lockdown, DR_L_W) { + l_popIncomingPersistentQueue; + } + + transition({NO_W, O_W, O_DR_W}, {Unlockdown, Own_Lock_or_Unlock}) { + l_popIncomingPersistentQueue; + } } diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm new file mode 100644 index 0000000000..550a36ae00 --- /dev/null +++ b/src/mem/protocol/MOESI_CMP_token-dma.sm @@ -0,0 +1,165 @@ +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +machine(DMA, "DMA Controller") +: int request_latency +{ + + MessageBuffer responseFromDir, network="From", virtual_network="0", ordered="true", no_vector="true"; + MessageBuffer reqToDirectory, network="To", virtual_network="5", ordered="false", no_vector="true"; + + enumeration(State, desc="DMA states", default="DMA_State_READY") { + READY, desc="Ready to accept a new request"; + BUSY_RD, desc="Busy: currently processing a request"; + BUSY_WR, desc="Busy: currently processing a request"; + } + + enumeration(Event, desc="DMA events") { + ReadRequest, desc="A new read request"; + WriteRequest, desc="A new write request"; + Data, desc="Data from a DMA memory read"; + Ack, desc="DMA write to memory completed"; + } + + external_type(DMASequencer) { + void ackCallback(); + void dataCallback(DataBlock); + } + + MessageBuffer mandatoryQueue, ordered="false", no_vector="true"; + DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])', no_vector="true"; + State cur_state, no_vector="true"; + + State getState(Address addr) { + return cur_state; + } + void setState(Address addr, State state) { + cur_state := state; + } + + out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="..."); + + in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") { + if (dmaRequestQueue_in.isReady()) { + peek(dmaRequestQueue_in, SequencerMsg) { + if (in_msg.Type == SequencerRequestType:LD ) { + trigger(Event:ReadRequest, in_msg.LineAddress); + } else if (in_msg.Type == SequencerRequestType:ST) { + trigger(Event:WriteRequest, in_msg.LineAddress); + } else { + error("Invalid request type"); + } + } + } + } + + in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") { + if (dmaResponseQueue_in.isReady()) { + peek( dmaResponseQueue_in, DMAResponseMsg) { + if (in_msg.Type == DMAResponseType:ACK) { + trigger(Event:Ack, in_msg.LineAddress); + } else if (in_msg.Type == DMAResponseType:DATA) { + trigger(Event:Data, in_msg.LineAddress); + } else { + error("Invalid response type"); + } + } + } + } + + action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") { + peek(dmaRequestQueue_in, SequencerMsg) { + enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) { + out_msg.PhysicalAddress := in_msg.PhysicalAddress; + out_msg.LineAddress := in_msg.LineAddress; + out_msg.Type := DMARequestType:READ; + out_msg.Requestor := machineID; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") { + peek(dmaRequestQueue_in, SequencerMsg) { + enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) { + out_msg.PhysicalAddress := in_msg.PhysicalAddress; + out_msg.LineAddress := in_msg.LineAddress; + out_msg.Type := DMARequestType:WRITE; + out_msg.Requestor := machineID; + out_msg.DataBlk := in_msg.DataBlk; + out_msg.Len := in_msg.Len; + out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.MessageSize := MessageSizeType:Writeback_Control; + } + } + } + + action(a_ackCallback, "a", desc="Notify dma controller that write request completed") { + peek (dmaResponseQueue_in, DMAResponseMsg) { + dma_sequencer.ackCallback(); + } + } + + action(d_dataCallback, "d", desc="Write data to dma sequencer") { + peek (dmaResponseQueue_in, DMAResponseMsg) { + dma_sequencer.dataCallback(in_msg.DataBlk); + } + } + + action(p_popRequestQueue, "p", desc="Pop request queue") { + dmaRequestQueue_in.dequeue(); + } + + action(p_popResponseQueue, "\p", desc="Pop request queue") { + dmaResponseQueue_in.dequeue(); + } + + transition(READY, ReadRequest, BUSY_RD) { + s_sendReadRequest; + p_popRequestQueue; + } + + transition(READY, WriteRequest, BUSY_WR) { + s_sendWriteRequest; + p_popRequestQueue; + } + + transition(BUSY_RD, Data, READY) { + d_dataCallback; + p_popResponseQueue; + } + + transition(BUSY_WR, Ack, READY) { + a_ackCallback; + p_popResponseQueue; + } +} diff --git a/src/mem/protocol/MOESI_CMP_token-msg.sm b/src/mem/protocol/MOESI_CMP_token-msg.sm index 2a75ce6448..40c16b5e18 100644 --- a/src/mem/protocol/MOESI_CMP_token-msg.sm +++ b/src/mem/protocol/MOESI_CMP_token-msg.sm @@ -59,8 +59,10 @@ enumeration(CoherenceResponseType, desc="...") { // TriggerType enumeration(TriggerType, desc="...") { - REQUEST_TIMEOUT, desc="See corresponding event"; + REQUEST_TIMEOUT, desc="See corresponding event"; USE_TIMEOUT, desc="See corresponding event"; + DATA, desc="data for dma read response"; + DATA_ALL_TOKENS, desc="data and all tokens for dma write response"; } // TriggerMsg @@ -111,13 +113,45 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") { MessageSizeType MessageSize, desc="size category of the message"; } -GenericRequestType convertToGenericType(CoherenceRequestType type) { - if(type == CoherenceRequestType:GETS) { - return GenericRequestType:GETS; - } else if(type == CoherenceRequestType:GETX) { - return GenericRequestType:GETX; - } else { - DEBUG_EXPR(type); - error("invalid CoherenceRequestType"); - } +enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") { + READ, desc="Memory Read"; + WRITE, desc="Memory Write"; + NULL, desc="Invalid"; } + +enumeration(DMAResponseType, desc="...", default="DMAResponseType_NULL") { + DATA, desc="DATA read"; + ACK, desc="ACK write"; + NULL, desc="Invalid"; +} + +structure(DMARequestMsg, desc="...", interface="NetworkMessage") { + DMARequestType Type, desc="Request type (read/write)"; + Address PhysicalAddress, desc="Physical address for this request"; + Address LineAddress, desc="Line address for this request"; + MachineID Requestor, desc="Node who initiated the request"; + NetDest Destination, desc="Destination"; + DataBlock DataBlk, desc="DataBlk attached to this request"; + int Len, desc="The length of the request"; + MessageSizeType MessageSize, desc="size category of the message"; +} + +structure(DMAResponseMsg, desc="...", interface="NetworkMessage") { + DMAResponseType Type, desc="Response type (DATA/ACK)"; + Address PhysicalAddress, desc="Physical address for this request"; + Address LineAddress, desc="Line address for this request"; + NetDest Destination, desc="Destination"; + DataBlock DataBlk, desc="DataBlk attached to this request"; + MessageSizeType MessageSize, desc="size category of the message"; +} + +//GenericRequestType convertToGenericType(CoherenceRequestType type) { +// if(type == CoherenceRequestType:GETS) { +// return GenericRequestType:GETS; +// } else if(type == CoherenceRequestType:GETX) { +// return GenericRequestType:GETX; +// } else { +// DEBUG_EXPR(type); +// error("invalid CoherenceRequestType"); +// } +//} diff --git a/src/mem/protocol/MOESI_CMP_token.slicc b/src/mem/protocol/MOESI_CMP_token.slicc index ae4a6d6ec6..a41226f90e 100644 --- a/src/mem/protocol/MOESI_CMP_token.slicc +++ b/src/mem/protocol/MOESI_CMP_token.slicc @@ -2,4 +2,5 @@ MOESI_CMP_token-msg.sm MOESI_CMP_token-L1cache.sm MOESI_CMP_token-L2cache.sm MOESI_CMP_token-dir.sm +MOESI_CMP_token-dma.sm standard_CMP-protocol.sm diff --git a/src/mem/protocol/RubySlicc_Util.sm b/src/mem/protocol/RubySlicc_Util.sm index 312682bd75..e1771448fa 100644 --- a/src/mem/protocol/RubySlicc_Util.sm +++ b/src/mem/protocol/RubySlicc_Util.sm @@ -52,7 +52,6 @@ void dirProfileCoherenceRequest(NodeID node, bool needCLB); bool isPerfectProtocol(); bool L1trainsPrefetcher(); int max_tokens(); -int N_tokens(); bool distributedPersistentEnabled(); Address setOffset(Address addr, int offset); Address makeLineAddress(Address addr); diff --git a/src/mem/ruby/SConscript b/src/mem/ruby/SConscript index 0c8423c854..3559f042f2 100644 --- a/src/mem/ruby/SConscript +++ b/src/mem/ruby/SConscript @@ -114,6 +114,7 @@ MakeInclude('system/MachineID.hh') MakeInclude('system/MemoryControl.hh') MakeInclude('system/NodeID.hh') MakeInclude('system/PerfectCacheMemory.hh') +MakeInclude('system/PersistentTable.hh') MakeInclude('system/Sequencer.hh') MakeInclude('system/TBETable.hh') MakeInclude('system/TimerTable.hh') diff --git a/src/mem/ruby/common/NetDest.cc b/src/mem/ruby/common/NetDest.cc index 32771235ff..35bb4ec43b 100644 --- a/src/mem/ruby/common/NetDest.cc +++ b/src/mem/ruby/common/NetDest.cc @@ -133,13 +133,14 @@ NodeID NetDest::elementAt(MachineID index) { return m_bits[vecIndex(index)].elementAt(bitIndex(index.num)); } -NodeID NetDest::smallestElement() const +MachineID NetDest::smallestElement() const { assert(count() > 0); for (int i=0; i getAllDest(); - NodeID smallestElement() const; + MachineID smallestElement() const; MachineID smallestElement(MachineType machine) const; void setSize(); diff --git a/src/mem/ruby/config/MOESI_CMP_token.rb b/src/mem/ruby/config/MOESI_CMP_token.rb new file mode 100644 index 0000000000..ba963dc060 --- /dev/null +++ b/src/mem/ruby/config/MOESI_CMP_token.rb @@ -0,0 +1,92 @@ + +require "cfg.rb" +require "util.rb" + + +class MOESI_CMP_token_L1CacheController < L1CacheController + attr :icache, :dcache + attr :num_l2_controllers + attr :n_tokens + def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers, n_tokens) + super(obj_name, mach_type, [icache, dcache], sequencer) + @icache = icache + @dcache = dcache + @num_l2_controllers = num_l2_controllers + @n_tokens = n_tokens + end + def argv() + num_select_bits = log_int(num_l2_controllers) + num_block_bits = log_int(RubySystem.block_size_bytes) + + l2_select_low_bit = num_block_bits + + vec = super() + vec += " icache " + @icache.obj_name + vec += " dcache " + @dcache.obj_name + vec += " l1_request_latency " + l1_request_latency.to_s + vec += " l1_response_latency " + l1_response_latency.to_s + vec += " l2_select_low_bit " + l2_select_low_bit.to_s + vec += " l2_select_num_bits " + num_select_bits.to_s + vec += " N_tokens " + n_tokens.to_s + vec += " retry_threshold " + retry_threshold.to_s + vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s + vec += " dynamic_timeout_enabled " + dynamic_timeout_enabled.to_s + + return vec + end +end + +class MOESI_CMP_token_L2CacheController < CacheController + attr :cache + attr :n_tokens + def initialize(obj_name, mach_type, cache, n_tokens) + super(obj_name, mach_type, [cache]) + @cache = cache + @n_tokens = n_tokens + end + def argv() + vec = super() + vec += " cache " + @cache.obj_name + vec += " l2_request_latency " + l2_request_latency.to_s + vec += " l2_response_latency " + l2_response_latency.to_s + vec += " N_tokens " + n_tokens.to_s + vec += " filtering_enabled " + filtering_enabled.to_s + return vec + end +end + + +class MOESI_CMP_token_DirectoryController < DirectoryController + attr :num_l2_controllers + def initialize(obj_name, mach_type, directory, memory_control, num_l2_controllers) + super(obj_name, mach_type, directory, memory_control) + @num_l2_controllers = num_l2_controllers + end + def argv() + num_select_bits = log_int(num_l2_controllers) + num_block_bits = log_int(RubySystem.block_size_bytes) + + l2_select_low_bit = num_block_bits + + vec = super() + vec += " directory_latency "+directory_latency.to_s + vec += " l2_select_low_bit " + l2_select_low_bit.to_s + vec += " l2_select_num_bits " + num_select_bits.to_s + vec += " distributed_persistent "+distributed_persistent.to_s + vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s + return vec + end + +end + +class MOESI_CMP_token_DMAController < DMAController + def initialize(obj_name, mach_type, dma_sequencer) + super(obj_name, mach_type, dma_sequencer) + end + def argv() + vec = super + vec += " request_latency "+request_latency.to_s + vec += " response_latency "+response_latency.to_s + return vec + end +end diff --git a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb index 83020742e2..566055f746 100644 --- a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb +++ b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb @@ -12,13 +12,13 @@ RubySystem.reset # default values num_cores = 2 -l1_icache_size_kb = 32 +l1_icache_size_bytes = 32768 l1_icache_assoc = 8 l1_icache_latency = 1 -l1_dcache_size_kb = 32 +l1_dcache_size_bytes = 32768 l1_dcache_assoc = 8 l1_dcache_latency = 1 -l2_cache_size_kb = 2048 # total size (sum of all banks) +l2_cache_size_bytes = 2048 # total size (sum of all banks) l2_cache_assoc = 16 l2_cache_latency = 12 num_l2_banks = num_cores @@ -26,7 +26,7 @@ num_memories = 1 memory_size_mb = 1024 num_dma = 1 -protocol = "MESI_CMP_directory" +protocol = "MOESI_CMP_token" # check for overrides @@ -43,9 +43,20 @@ for i in 0..$*.size-1 do elsif $*[i] == "-s" memory_size_mb = $*[i+1].to_i i = i + 1 + elsif $*[i] == "-C" + l1_dcache_size_bytes = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-A" + l1_dcache_assoc = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-D" + num_dma = $*[i+1].to_i + i = i + 1 end end +n_tokens = num_cores + 1 + net_ports = Array.new iface_ports = Array.new @@ -54,10 +65,19 @@ iface_ports = Array.new require protocol+".rb" num_cores.times { |n| - icache = SetAssociativeCache.new("l1i_"+n.to_s, l1_icache_size_kb, l1_icache_latency, l1_icache_assoc, "PSEUDO_LRU") - dcache = SetAssociativeCache.new("l1d_"+n.to_s, l1_dcache_size_kb, l1_dcache_latency, l1_dcache_assoc, "PSEUDO_LRU") + icache = SetAssociativeCache.new("l1i_"+n.to_s, l1_icache_size_bytes, l1_icache_latency, l1_icache_assoc, "PSEUDO_LRU") + dcache = SetAssociativeCache.new("l1d_"+n.to_s, l1_dcache_size_bytes, l1_dcache_latency, l1_dcache_assoc, "PSEUDO_LRU") sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache) iface_ports << sequencer + if protocol == "MOESI_CMP_token" + net_ports << MOESI_CMP_token_L1CacheController.new("L1CacheController_"+n.to_s, + "L1Cache", + icache, dcache, + sequencer, + num_l2_banks, + n_tokens) + end + if protocol == "MOESI_CMP_directory" net_ports << MOESI_CMP_directory_L1CacheController.new("L1CacheController_"+n.to_s, "L1Cache", @@ -75,7 +95,14 @@ num_cores.times { |n| end } num_l2_banks.times { |n| - cache = SetAssociativeCache.new("l2u_"+n.to_s, l2_cache_size_kb/num_l2_banks, l2_cache_latency, l2_cache_assoc, "PSEUDO_LRU") + cache = SetAssociativeCache.new("l2u_"+n.to_s, l2_cache_size_bytes/num_l2_banks, l2_cache_latency, l2_cache_assoc, "PSEUDO_LRU") + if protocol == "MOESI_CMP_token" + net_ports << MOESI_CMP_token_L2CacheController.new("L2CacheController_"+n.to_s, + "L2Cache", + cache, + n_tokens) + end + if protocol == "MOESI_CMP_directory" net_ports << MOESI_CMP_directory_L2CacheController.new("L2CacheController_"+n.to_s, "L2Cache", @@ -93,6 +120,14 @@ num_l2_banks.times { |n| num_memories.times { |n| directory = DirectoryMemory.new("DirectoryMemory_"+n.to_s, memory_size_mb/num_memories) memory_control = MemoryControl.new("MemoryControl_"+n.to_s) + if protocol == "MOESI_CMP_token" + net_ports << MOESI_CMP_token_DirectoryController.new("DirectoryController_"+n.to_s, + "Directory", + directory, + memory_control, + num_l2_banks) + end + if protocol == "MOESI_CMP_directory" net_ports << MOESI_CMP_directory_DirectoryController.new("DirectoryController_"+n.to_s, "Directory", @@ -111,6 +146,12 @@ num_memories.times { |n| num_dma.times { |n| dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s) iface_ports << dma_sequencer + if protocol == "MOESI_CMP_token" + net_ports << MOESI_CMP_token_DMAController.new("DMAController_"+n.to_s, + "DMA", + dma_sequencer) + end + if protocol == "MOESI_CMP_directory" net_ports << MOESI_CMP_directory_DMAController.new("DMAController_"+n.to_s, "DMA", diff --git a/src/mem/ruby/config/cfg.rb b/src/mem/ruby/config/cfg.rb index f2564e1d32..c470ca92f7 100644 --- a/src/mem/ruby/config/cfg.rb +++ b/src/mem/ruby/config/cfg.rb @@ -538,7 +538,6 @@ class MemoryControl < LibRubyObject end end - class Sequencer < IfacePort def cppClassName() diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb index bb054ec4eb..f338f4e3fc 100644 --- a/src/mem/ruby/config/defaults.rb +++ b/src/mem/ruby/config/defaults.rb @@ -167,6 +167,33 @@ class MOESI_CMP_directory_DMAController < DMAController default_param :response_latency, Integer, 6 end +## MOESI_CMP_token protocol + +class MOESI_CMP_token_L1CacheController < L1CacheController + default_param :l1_request_latency, Integer, 2 + default_param :l1_response_latency, Integer, 2 + default_param :retry_threshold, Integer, 1 + default_param :fixed_timeout_latency, Integer, 300 + default_param :dynamic_timeout_enabled, Boolean, true +end + +class MOESI_CMP_token_L2CacheController < CacheController + default_param :l2_request_latency, Integer, 2 + default_param :l2_response_latency, Integer, 2 + default_param :filtering_enabled, Boolean, true +end + +class MOESI_CMP_token_DirectoryController < DirectoryController + default_param :directory_latency, Integer, 6 + default_param :distributed_persistent, Boolean, true + default_param :fixed_timeout_latency, Integer, 300 +end + +class MOESI_CMP_token_DMAController < DMAController + default_param :request_latency, Integer, 6 + default_param :response_latency, Integer, 6 +end + ## MOESI_hammer protocol class MOESI_hammer_CacheController < L1CacheController diff --git a/src/mem/ruby/system/PersistentTable.cc b/src/mem/ruby/system/PersistentTable.cc index 1e056f6e53..58b67ea60f 100644 --- a/src/mem/ruby/system/PersistentTable.cc +++ b/src/mem/ruby/system/PersistentTable.cc @@ -27,44 +27,33 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "PersistentTable.hh" -#include "NetDest.h" -#include "Map.h" -#include "Address.h" -#include "AbstractChip.h" -#include "util.h" +#include "mem/ruby/system/PersistentTable.hh" +#include "mem/gems_common/util.hh" // randomize so that handoffs are not locality-aware // int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}; // int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; -class PersistentTableEntry { -public: - NetDest m_starving; - NetDest m_marked; - NetDest m_request_to_write; -}; - -PersistentTable::PersistentTable(AbstractChip* chip_ptr, int version) +PersistentTable::PersistentTable() { - m_chip_ptr = chip_ptr; m_map_ptr = new Map; - m_version = version; } PersistentTable::~PersistentTable() { delete m_map_ptr; m_map_ptr = NULL; - m_chip_ptr = NULL; } -void PersistentTable::persistentRequestLock(const Address& address, MachineID locker, AccessType type) +void PersistentTable::persistentRequestLock(const Address& address, + MachineID locker, + AccessType type) { // if (locker == m_chip_ptr->getID() ) - // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker << " requesting lock for " << address << endl; + // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker + // << " requesting lock for " << address << endl; // MachineID locker = (MachineID) persistent_randomize[llocker]; @@ -79,7 +68,11 @@ void PersistentTable::persistentRequestLock(const Address& address, MachineID lo m_map_ptr->add(address, entry); } else { PersistentTableEntry& entry = m_map_ptr->lookup(address); - assert(!(entry.m_starving.isElement(locker))); // Make sure we're not already in the locked set + + // + // Make sure we're not already in the locked set + // + assert(!(entry.m_starving.isElement(locker))); entry.m_starving.add(locker); if (type == AccessType_Write) { @@ -89,17 +82,23 @@ void PersistentTable::persistentRequestLock(const Address& address, MachineID lo } } -void PersistentTable::persistentRequestUnlock(const Address& address, MachineID unlocker) +void PersistentTable::persistentRequestUnlock(const Address& address, + MachineID unlocker) { // if (unlocker == m_chip_ptr->getID() ) - // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker << " requesting unlock for " << address << endl; + // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker + // << " requesting unlock for " << address << endl; // MachineID unlocker = (MachineID) persistent_randomize[uunlocker]; assert(address == line_address(address)); assert(m_map_ptr->exist(address)); PersistentTableEntry& entry = m_map_ptr->lookup(address); - assert(entry.m_starving.isElement(unlocker)); // Make sure we're in the locked set + + // + // Make sure we're in the locked set + // + assert(entry.m_starving.isElement(unlocker)); assert(entry.m_marked.isSubset(entry.m_starving)); entry.m_starving.remove(unlocker); entry.m_marked.remove(unlocker); @@ -113,13 +112,20 @@ void PersistentTable::persistentRequestUnlock(const Address& address, MachineID } } -bool PersistentTable::okToIssueStarving(const Address& address) const +bool PersistentTable::okToIssueStarving(const Address& address, + MachineID machId) const { assert(address == line_address(address)); if (!m_map_ptr->exist(address)) { - return true; // No entry present - } else if (m_map_ptr->lookup(address).m_starving.isElement( (MachineID) {MachineType_L1Cache, m_version})) { - return false; // We can't issue another lockdown until are previous unlock has occurred + // + // No entry present + // + return true; + } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) { + // + // We can't issue another lockdown until are previous unlock has occurred + // + return false; } else { return (m_map_ptr->lookup(address).m_marked.isEmpty()); } @@ -130,9 +136,7 @@ MachineID PersistentTable::findSmallest(const Address& address) const assert(address == line_address(address)); assert(m_map_ptr->exist(address)); const PersistentTableEntry& entry = m_map_ptr->lookup(address); - // cout << "Node " << m_chip_ptr->getID() << " returning " << persistent_randomize[entry.m_starving.smallestElement()] << " for findSmallest(" << address << ")" << endl; - // return (MachineID) persistent_randomize[entry.m_starving.smallestElement()]; - return (MachineID) { MachineType_L1Cache, entry.m_starving.smallestElement() }; + return entry.m_starving.smallestElement(); } AccessType PersistentTable::typeOfSmallest(const Address& address) const @@ -140,7 +144,7 @@ AccessType PersistentTable::typeOfSmallest(const Address& address) const assert(address == line_address(address)); assert(m_map_ptr->exist(address)); const PersistentTableEntry& entry = m_map_ptr->lookup(address); - if (entry.m_request_to_write.isElement((MachineID) {MachineType_L1Cache, entry.m_starving.smallestElement()})) { + if (entry.m_request_to_write.isElement(entry.m_starving.smallestElement())) { return AccessType_Write; } else { return AccessType_Read; @@ -152,8 +156,16 @@ void PersistentTable::markEntries(const Address& address) assert(address == line_address(address)); if (m_map_ptr->exist(address)) { PersistentTableEntry& entry = m_map_ptr->lookup(address); - assert(entry.m_marked.isEmpty()); // None should be marked - entry.m_marked = entry.m_starving; // Mark all the nodes currently in the table + + // + // None should be marked + // + assert(entry.m_marked.isEmpty()); + + // + // Mark all the nodes currently in the table + // + entry.m_marked = entry.m_starving; } } @@ -177,7 +189,6 @@ int PersistentTable::countStarvingForAddress(const Address& address) const int PersistentTable::countReadStarvingForAddress(const Address& address) const { - int count = 0; if (m_map_ptr->exist(address)) { PersistentTableEntry& entry = m_map_ptr->lookup(address); return (entry.m_starving.count() - entry.m_request_to_write.count()); @@ -187,4 +198,7 @@ int PersistentTable::countReadStarvingForAddress(const Address& address) const } } +void PersistentTable::print(ostream& out) const +{ +} diff --git a/src/mem/ruby/system/PersistentTable.hh b/src/mem/ruby/system/PersistentTable.hh index ab000843d1..8cbb488179 100644 --- a/src/mem/ruby/system/PersistentTable.hh +++ b/src/mem/ruby/system/PersistentTable.hh @@ -30,20 +30,26 @@ #ifndef PersistentTable_H #define PersistentTable_H -#include "Global.h" -#include "MachineID.h" -#include "AccessType.h" +#include "mem/ruby/common/Global.hh" +#include "mem/gems_common/Map.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/system/MachineID.hh" +#include "mem/protocol/AccessType.hh" +#include "mem/ruby/common/NetDest.hh" -class AbstractChip; +class PersistentTableEntry { +public: + void print(ostream& out) const {} -template class Map; -class Address; -class PersistentTableEntry; + NetDest m_starving; + NetDest m_marked; + NetDest m_request_to_write; +}; class PersistentTable { public: // Constructors - PersistentTable(AbstractChip* chip_ptr, int version); + PersistentTable(); // Destructor ~PersistentTable(); @@ -51,7 +57,7 @@ public: // Public Methods void persistentRequestLock(const Address& address, MachineID locker, AccessType type); void persistentRequestUnlock(const Address& address, MachineID unlocker); - bool okToIssueStarving(const Address& address) const; + bool okToIssueStarving(const Address& address, MachineID machID) const; MachineID findSmallest(const Address& address) const; AccessType typeOfSmallest(const Address& address) const; void markEntries(const Address& address); @@ -71,17 +77,12 @@ private: // Data Members (m_prefix) Map* m_map_ptr; - AbstractChip* m_chip_ptr; - int m_version; }; -// Output operator declaration -ostream& operator<<(ostream& out, const PersistentTable& obj); - // ******************* Definitions ******************* // Output operator definition -extern inline +extern inline ostream& operator<<(ostream& out, const PersistentTable& obj) { obj.print(out); @@ -89,4 +90,13 @@ ostream& operator<<(ostream& out, const PersistentTable& obj) return out; } +// Output operator definition +extern inline +ostream& operator<<(ostream& out, const PersistentTableEntry& obj) +{ + obj.print(out); + out << flush; + return out; +} + #endif //PersistentTable_H diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript index 496fce2fd5..4ca1af114c 100644 --- a/src/mem/ruby/system/SConscript +++ b/src/mem/ruby/system/SConscript @@ -38,6 +38,7 @@ Source('DirectoryMemory.cc') Source('CacheMemory.cc') Source('MemoryControl.cc') Source('MemoryNode.cc') +Source('PersistentTable.cc') Source('RubyPort.cc') Source('Sequencer.cc', Werror=False) Source('System.cc') From 295516a590b6e47c9a881f193027447e500c749c Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 18:00:41 -0800 Subject: [PATCH 160/160] m5: refreshed the ruby memtest regression stats --- tests/configs/memtest-ruby.py | 5 +- .../ref/alpha/linux/memtest-ruby/config.ini | 4 +- .../ref/alpha/linux/memtest-ruby/ruby.stats | 782 ++++++++---------- .../ref/alpha/linux/memtest-ruby/simerr | 148 ++-- .../ref/alpha/linux/memtest-ruby/simout | 12 +- .../ref/alpha/linux/memtest-ruby/stats.txt | 42 +- 6 files changed, 460 insertions(+), 533 deletions(-) diff --git a/tests/configs/memtest-ruby.py b/tests/configs/memtest-ruby.py index 00a668a7b4..c564ec600e 100644 --- a/tests/configs/memtest-ruby.py +++ b/tests/configs/memtest-ruby.py @@ -35,7 +35,10 @@ nb_cores = 8 cpus = [ MemTest() for i in xrange(nb_cores) ] import ruby_config -ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", nb_cores) +ruby_memory = ruby_config.generate("MI_example-homogeneous.rb", + cores = nb_cores, + cache_size = 256, + cache_assoc = 2) # system simulated system = System(cpu = cpus, funcmem = PhysicalMemory(), diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/config.ini b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/config.ini index 99cec587fb..b595ebc5e6 100644 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/config.ini +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/config.ini @@ -160,8 +160,10 @@ latency=30000 latency_var=0 null=false num_cpus=8 +num_dmas=1 phase=0 -range=0:134217727 +ports_per_core=2 +range=0:1073741823 stats_file=ruby.stats zero=false port=system.membus.port[8] diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats index 28a2e20959..98cf9b30f2 100644 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/ruby.stats @@ -23,8 +23,6 @@ Directory_Controller config: DirectoryController_0 buffer_size: 0 directory_latency: 6 directory_name: DirectoryMemory_0 - dma_select_low_bit: 6 - dma_select_num_bits: 0 memory_controller_name: MemoryControl_0 number_of_TBEs: 256 recycle_latency: 10 @@ -111,92 +109,92 @@ L1Cache_Controller config: L1CacheController_7 transitions_per_cycle: 32 Cache config: l1u_0 controller: L1CacheController_0 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_1 controller: L1CacheController_1 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_2 controller: L1CacheController_2 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_3 controller: L1CacheController_3 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_4 controller: L1CacheController_4 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_5 controller: L1CacheController_5 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_6 controller: L1CacheController_6 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 Cache config: l1u_7 controller: L1CacheController_7 - cache_associativity: 8 - num_cache_sets_bits: 2 - num_cache_sets: 4 - cache_set_size_bytes: 256 - cache_set_size_Kbytes: 0.25 - cache_set_size_Mbytes: 0.000244141 - cache_size_bytes: 2048 - cache_size_Kbytes: 2 - cache_size_Mbytes: 0.00195312 + cache_associativity: 2 + num_cache_sets_bits: 1 + num_cache_sets: 2 + cache_set_size_bytes: 128 + cache_set_size_Kbytes: 0.125 + cache_set_size_Mbytes: 0.00012207 + cache_size_bytes: 256 + cache_size_Kbytes: 0.25 + cache_size_Mbytes: 0.000244141 DirectoryMemory Global Config: number of directory memories: 1 total memory size bytes: 1073741824 @@ -390,34 +388,34 @@ periodic_stats_period: 1000000 ================ End RubySystem Configuration Print ================ -Real time: Nov/03/2009 14:55:53 +Real time: Nov/18/2009 17:42:31 Profiler Stats -------------- -Elapsed_time_in_seconds: 892 -Elapsed_time_in_minutes: 14.8667 -Elapsed_time_in_hours: 0.247778 -Elapsed_time_in_days: 0.0103241 +Elapsed_time_in_seconds: 3924 +Elapsed_time_in_minutes: 65.4 +Elapsed_time_in_hours: 1.09 +Elapsed_time_in_days: 0.0454167 -Virtual_time_in_seconds: 889.79 -Virtual_time_in_minutes: 14.8298 -Virtual_time_in_hours: 0.247164 -Virtual_time_in_days: 0.0102985 +Virtual_time_in_seconds: 3921.96 +Virtual_time_in_minutes: 65.366 +Virtual_time_in_hours: 1.08943 +Virtual_time_in_days: 0.0453931 -Ruby_current_time: 31693011 +Ruby_current_time: 60455259 Ruby_start_time: 1 -Ruby_cycles: 31693010 +Ruby_cycles: 60455258 -mbytes_resident: 153.086 -mbytes_total: 1466.18 -resident_ratio: 0.104414 +mbytes_resident: 151.762 +mbytes_total: 2381.61 +resident_ratio: 0.0637255 Total_misses: 0 total_misses: 0 [ 0 0 0 0 0 0 0 0 ] user_misses: 0 [ 0 0 0 0 0 0 0 0 ] supervisor_misses: 0 [ 0 0 0 0 0 0 0 0 ] -ruby_cycles_executed: 253544088 [ 31693011 31693011 31693011 31693011 31693011 31693011 31693011 31693011 ] +ruby_cycles_executed: 483642072 [ 60455259 60455259 60455259 60455259 60455259 60455259 60455259 60455259 ] transactions_started: 0 [ 0 0 0 0 0 0 0 0 ] transactions_ended: 0 [ 0 0 0 0 0 0 0 0 ] @@ -426,40 +424,40 @@ misses_per_transaction: 0 [ 0 0 0 0 0 0 0 0 ] Memory control MemoryControl_0: - memory_total_requests: 1382929 - memory_reads: 691503 - memory_writes: 691242 - memory_refreshes: 66028 - memory_total_request_delays: 424685881 - memory_delays_per_request: 307.092 - memory_delays_in_input_queue: 89365268 - memory_delays_behind_head_of_bank_queue: 255462545 - memory_delays_stalled_at_head_of_bank_queue: 79858068 - memory_stalls_for_bank_busy: 12071979 + memory_total_requests: 1497259 + memory_reads: 748631 + memory_writes: 748628 + memory_refreshes: 125949 + memory_total_request_delays: 10693878 + memory_delays_per_request: 7.1423 + memory_delays_in_input_queue: 3751785 + memory_delays_behind_head_of_bank_queue: 352863 + memory_delays_stalled_at_head_of_bank_queue: 6589230 + memory_stalls_for_bank_busy: 1322551 memory_stalls_for_random_busy: 0 - memory_stalls_for_anti_starvation: 24463399 - memory_stalls_for_arbitration: 15522067 - memory_stalls_for_bus: 20396836 + memory_stalls_for_anti_starvation: 8817 + memory_stalls_for_arbitration: 1317249 + memory_stalls_for_bus: 2228686 memory_stalls_for_tfaw: 0 - memory_stalls_for_read_write_turnaround: 5970102 - memory_stalls_for_read_read_turnaround: 1433685 - accesses_per_bank: 43013 43694 43739 43577 43477 43549 43400 43520 43342 43265 43265 43165 43087 43280 43291 43090 42980 42992 43280 43172 42991 43123 43177 43217 43344 43024 43173 42922 42657 42936 42917 43270 + memory_stalls_for_read_write_turnaround: 1350744 + memory_stalls_for_read_read_turnaround: 361183 + accesses_per_bank: 46780 46744 46842 46810 46806 46792 46736 46774 46868 46766 46784 46766 46757 46844 46764 46814 46814 46756 46796 46862 46782 46782 46770 46838 46780 46720 46750 46754 46840 46760 46788 46820 Busy Controller Counts: -L1Cache-0:0 L1Cache-1:0 L1Cache-2:0 L1Cache-3:0 L1Cache-4:0 L1Cache-5:1 L1Cache-6:1 L1Cache-7:0 +L1Cache-0:0 L1Cache-1:0 L1Cache-2:0 L1Cache-3:0 L1Cache-4:0 L1Cache-5:0 L1Cache-6:0 L1Cache-7:0 Directory-0:0 DMA-0:0 Busy Bank Count:0 -sequencer_requests_outstanding: [binsize: 1 max: 16 count: 745817 average: 11.8049 | standard deviation: 3.3976 | 0 1090 2744 5398 9406 15430 23546 33441 44604 54944 64080 70066 72710 71820 68564 65093 142881 ] +sequencer_requests_outstanding: [binsize: 1 max: 16 count: 749581 average: 15.7532 | standard deviation: 1.38784 | 0 475 726 892 999 1179 1408 1673 2066 2371 2666 3000 3297 3618 4065 5733 715413 ] All Non-Zero Cycle Demand Cache Accesses ---------------------------------------- -miss_latency: [binsize: 128 max: 20699 count: 745717 average: 3865 | standard deviation: 2351.52 | 21754 2058 3346 6576 8668 8377 7613 8584 10100 11818 13663 13336 12389 13097 16379 17199 16086 16157 17043 17386 16626 18695 19215 16901 15943 17630 18236 16024 15652 16370 15646 14274 14424 15394 13703 11981 12957 13262 11516 10766 11366 11178 9497 9444 9929 9046 7835 7972 8271 7278 6362 6864 6580 5689 5240 5566 5224 4337 4206 4581 4050 3302 3393 3480 2968 2642 2730 2675 2196 2020 2139 1952 1510 1484 1488 1240 1021 1076 1110 871 774 775 735 600 545 491 542 356 366 385 321 272 258 246 231 160 191 163 144 116 138 123 95 82 90 73 47 56 70 54 50 36 38 34 32 33 29 26 8 19 23 20 12 16 18 13 15 7 7 11 11 3 15 4 12 6 7 10 8 4 1 5 5 3 3 4 3 0 0 2 1 1 0 2 0 1 1 2 0 0 0 1 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 0 0 0 0 0 0 ] -miss_latency_2: [binsize: 128 max: 20699 count: 485064 average: 3865.43 | standard deviation: 2349.44 | 14100 1323 2132 4283 5700 5430 4976 5577 6639 7727 8762 8690 7975 8507 10567 11178 10575 10466 11091 11329 10802 12188 12472 10976 10321 11551 11898 10321 10187 10655 10222 9350 9367 9968 8885 7759 8434 8727 7594 6995 7447 7302 6134 6111 6428 5954 5120 5195 5346 4711 4145 4468 4350 3682 3455 3602 3384 2814 2709 2987 2632 2198 2209 2285 1930 1707 1742 1703 1478 1304 1384 1271 977 984 932 792 643 722 716 595 501 484 477 379 343 324 345 219 229 259 204 176 169 153 139 105 126 110 91 71 94 78 67 57 65 44 35 33 41 39 29 26 26 22 18 18 15 21 6 12 13 14 5 9 11 12 7 5 4 5 10 1 11 4 6 5 6 6 7 2 0 4 2 3 3 3 2 0 0 2 1 1 0 1 0 0 0 1 0 0 0 1 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 0 0 0 0 0 ] -miss_latency_3: [binsize: 128 max: 20151 count: 260653 average: 3864.21 | standard deviation: 2355.37 | 7654 735 1214 2293 2968 2947 2637 3007 3461 4091 4901 4646 4414 4590 5812 6021 5511 5691 5952 6057 5824 6507 6743 5925 5622 6079 6338 5703 5465 5715 5424 4924 5057 5426 4818 4222 4523 4535 3922 3771 3919 3876 3363 3333 3501 3092 2715 2777 2925 2567 2217 2396 2230 2007 1785 1964 1840 1523 1497 1594 1418 1104 1184 1195 1038 935 988 972 718 716 755 681 533 500 556 448 378 354 394 276 273 291 258 221 202 167 197 137 137 126 117 96 89 93 92 55 65 53 53 45 44 45 28 25 25 29 12 23 29 15 21 10 12 12 14 15 14 5 2 7 10 6 7 7 7 1 8 2 3 6 1 2 4 0 6 1 1 4 1 2 1 1 3 0 0 1 1 0 0 0 0 0 0 1 0 1 1 1 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 0 0 0 0 0 0 0 0 0 0 ] +miss_latency: [binsize: 16 max: 2089 count: 749568 average: 1269.27 | standard deviation: 184.346 | 706 46 2 38 9 9 11 1 3 18 234 183 253 263 195 167 114 113 80 74 124 134 192 223 283 302 368 333 358 349 310 281 264 303 303 313 381 411 416 435 426 499 501 538 535 532 518 525 525 512 542 549 555 659 781 726 1112 1090 2204 3346 2562 5313 3505 7093 8407 5152 11332 6998 16292 21050 13121 29097 16803 34587 35992 18551 36492 19051 36733 37381 19033 37972 19036 35937 33738 16101 29532 14057 25324 22428 10173 18224 7932 13852 11409 4860 8441 3641 6175 4984 2172 3417 1391 2332 1751 697 1089 457 745 556 215 291 123 215 137 63 94 40 57 28 9 19 5 8 5 5 4 2 2 0 1 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 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 0 0 ] +miss_latency_2: [binsize: 16 max: 2059 count: 487448 average: 1269.28 | standard deviation: 183.834 | 432 31 2 21 7 7 8 1 1 8 150 118 169 171 119 101 77 70 54 51 73 78 128 142 175 205 218 217 223 230 208 191 173 202 219 188 238 265 274 281 284 338 317 343 345 351 350 322 342 355 341 355 368 421 494 491 737 709 1423 2160 1690 3504 2280 4639 5415 3375 7314 4535 10511 13782 8565 18932 10987 22355 23465 12092 23641 12545 24045 24209 12417 24627 12375 23363 21911 10475 19320 9131 16506 14610 6581 11831 5169 8995 7363 3196 5492 2339 3969 3226 1448 2182 890 1520 1118 446 700 293 484 359 146 173 86 141 81 42 61 28 39 21 7 13 3 7 2 3 3 1 2 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 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 0 0 0 0 ] +miss_latency_3: [binsize: 16 max: 2089 count: 262120 average: 1269.26 | standard deviation: 185.295 | 274 15 0 17 2 2 3 0 2 10 84 65 84 92 76 66 37 43 26 23 51 56 64 81 108 97 150 116 135 119 102 90 91 101 84 125 143 146 142 154 142 161 184 195 190 181 168 203 183 157 201 194 187 238 287 235 375 381 781 1186 872 1809 1225 2454 2992 1777 4018 2463 5781 7268 4556 10165 5816 12232 12527 6459 12851 6506 12688 13172 6616 13345 6661 12574 11827 5626 10212 4926 8818 7818 3592 6393 2763 4857 4046 1664 2949 1302 2206 1758 724 1235 501 812 633 251 389 164 261 197 69 118 37 74 56 21 33 12 18 7 2 6 2 1 3 2 1 1 0 0 1 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 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 0 0 ] All Non-Zero Cycle SW Prefetch Requests ------------------------------------ @@ -473,11 +471,11 @@ filter_action: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN Message Delayed Cycles ---------------------- -Total_delay_cycles: [binsize: 1 max: 34 count: 1491601 average: 0.00196835 | standard deviation: 0.175086 | 1491404 1 1 0 1 0 1 0 1 3 7 3 18 8 36 19 42 20 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] -Total_nonPF_delay_cycles: [binsize: 1 max: 34 count: 1491601 average: 0.00196835 | standard deviation: 0.175086 | 1491404 1 1 0 1 0 1 0 1 3 7 3 18 8 36 19 42 20 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] +Total_delay_cycles: [binsize: 1 max: 0 count: 1497256 average: 0 | standard deviation: 0 | 1497256 ] +Total_nonPF_delay_cycles: [binsize: 1 max: 0 count: 1497256 average: 0 | standard deviation: 0 | 1497256 ] virtual_network_0_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] - virtual_network_1_delay_cycles: [binsize: 1 max: 0 count: 745717 average: 0 | standard deviation: 0 | 745717 ] - virtual_network_2_delay_cycles: [binsize: 1 max: 34 count: 745884 average: 0.00393627 | standard deviation: 0.247579 | 745687 1 1 0 1 0 1 0 1 3 7 3 18 8 36 19 42 20 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ] + virtual_network_1_delay_cycles: [binsize: 1 max: 0 count: 748630 average: 0 | standard deviation: 0 | 748630 ] + virtual_network_2_delay_cycles: [binsize: 1 max: 0 count: 748626 average: 0 | standard deviation: 0 | 748626 ] virtual_network_3_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] virtual_network_4_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] virtual_network_5_delay_cycles: [binsize: 1 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] @@ -489,123 +487,87 @@ Total_nonPF_delay_cycles: [binsize: 1 max: 34 count: 1491601 average: 0.00196835 Resource Usage -------------- page_size: 4096 -user_time: 889 +user_time: 3921 system_time: 0 -page_reclaims: 39882 -page_faults: 0 +page_reclaims: 40455 +page_faults: 3 swaps: 0 -block_inputs: 32 -block_outputs: 144 +block_inputs: 0 +block_outputs: 0 Network Stats ------------- switch_0_inlinks: 2 switch_0_outlinks: 2 -links_utilized_percent_switch_0: 0.0919149 - links_utilized_percent_switch_0_link_0: 0.0367576 bw: 640000 base_latency: 1 - links_utilized_percent_switch_0_link_1: 0.147072 bw: 160000 base_latency: 1 +links_utilized_percent_switch_0: 0.386974 + links_utilized_percent_switch_0_link_0: 0.15479 bw: 640000 base_latency: 1 + links_utilized_percent_switch_0_link_1: 0.619159 bw: 160000 base_latency: 1 - outgoing_messages_switch_0_link_0_Response_Data: 93195 6710040 [ 0 93195 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_0_Writeback_Control: 93211 745688 [ 0 0 93211 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_1_Control: 93208 745664 [ 93208 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_1_Data: 86476 6226272 [ 86476 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_0_link_1_Response_Data: 6749 485928 [ 0 6749 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_0_Response_Data: 748630 53901360 [ 0 748630 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_0_Writeback_Control: 748626 5989008 [ 0 0 748626 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_1_Control: 748631 5989048 [ 748631 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_0_link_1_Data: 748628 53901216 [ 748628 0 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_1_inlinks: 2 switch_1_outlinks: 2 -links_utilized_percent_switch_1: 0.0919746 - links_utilized_percent_switch_1_link_0: 0.0367803 bw: 640000 base_latency: 1 - links_utilized_percent_switch_1_link_1: 0.147169 bw: 160000 base_latency: 1 +links_utilized_percent_switch_1: 0 + links_utilized_percent_switch_1_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_1_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_1_link_0_Response_Data: 93252 6714144 [ 0 93252 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_0_Writeback_Control: 93276 746208 [ 0 0 93276 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_1_Control: 93262 746096 [ 93262 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_1_Data: 86505 6228360 [ 86505 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_1_link_1_Response_Data: 6782 488304 [ 0 6782 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_2_inlinks: 2 switch_2_outlinks: 2 -links_utilized_percent_switch_2: 0.0919005 - links_utilized_percent_switch_2_link_0: 0.0367529 bw: 640000 base_latency: 1 - links_utilized_percent_switch_2_link_1: 0.147048 bw: 160000 base_latency: 1 +links_utilized_percent_switch_2: 0 + links_utilized_percent_switch_2_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_2_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_2_link_0_Response_Data: 93184 6709248 [ 0 93184 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_0_Writeback_Control: 93192 745536 [ 0 0 93192 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_1_Control: 93199 745592 [ 93199 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_1_Data: 86329 6215688 [ 86329 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_2_link_1_Response_Data: 6880 495360 [ 0 6880 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_3_inlinks: 2 switch_3_outlinks: 2 -links_utilized_percent_switch_3: 0.0919481 - links_utilized_percent_switch_3_link_0: 0.0367693 bw: 640000 base_latency: 1 - links_utilized_percent_switch_3_link_1: 0.147127 bw: 160000 base_latency: 1 +links_utilized_percent_switch_3: 0 + links_utilized_percent_switch_3_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_3_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_3_link_0_Response_Data: 93224 6712128 [ 0 93224 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_0_Writeback_Control: 93249 745992 [ 0 0 93249 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_1_Control: 93230 745840 [ 93230 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_1_Data: 86495 6227640 [ 86495 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_3_link_1_Response_Data: 6766 487152 [ 0 6766 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_4_inlinks: 2 switch_4_outlinks: 2 -links_utilized_percent_switch_4: 0.0919309 - links_utilized_percent_switch_4_link_0: 0.0367621 bw: 640000 base_latency: 1 - links_utilized_percent_switch_4_link_1: 0.1471 bw: 160000 base_latency: 1 +links_utilized_percent_switch_4: 0 + links_utilized_percent_switch_4_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_4_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_4_link_0_Response_Data: 93206 6710832 [ 0 93206 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_0_Writeback_Control: 93228 745824 [ 0 0 93228 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_1_Control: 93219 745752 [ 93219 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_1_Data: 86285 6212520 [ 86285 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_4_link_1_Response_Data: 6958 500976 [ 0 6958 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_5_inlinks: 2 switch_5_outlinks: 2 -links_utilized_percent_switch_5: 0.0919246 - links_utilized_percent_switch_5_link_0: 0.0367591 bw: 640000 base_latency: 1 - links_utilized_percent_switch_5_link_1: 0.14709 bw: 160000 base_latency: 1 +links_utilized_percent_switch_5: 0 + links_utilized_percent_switch_5_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_5_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_5_link_0_Response_Data: 93198 6710256 [ 0 93198 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_0_Writeback_Control: 93222 745776 [ 0 0 93222 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_1_Control: 93213 745704 [ 93213 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_1_Data: 86640 6238080 [ 86640 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_5_link_1_Response_Data: 6597 474984 [ 0 6597 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_6_inlinks: 2 switch_6_outlinks: 2 -links_utilized_percent_switch_6: 0.0919589 - links_utilized_percent_switch_6_link_0: 0.036773 bw: 640000 base_latency: 1 - links_utilized_percent_switch_6_link_1: 0.147145 bw: 160000 base_latency: 1 +links_utilized_percent_switch_6: 0 + links_utilized_percent_switch_6_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_6_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_6_link_0_Response_Data: 93233 6712776 [ 0 93233 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_0_Writeback_Control: 93260 746080 [ 0 0 93260 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_1_Control: 93245 745960 [ 93245 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_1_Data: 86585 6234120 [ 86585 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_6_link_1_Response_Data: 6687 481464 [ 0 6687 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_7_inlinks: 2 switch_7_outlinks: 2 -links_utilized_percent_switch_7: 0.0919419 - links_utilized_percent_switch_7_link_0: 0.0367696 bw: 640000 base_latency: 1 - links_utilized_percent_switch_7_link_1: 0.147114 bw: 160000 base_latency: 1 +links_utilized_percent_switch_7: 0 + links_utilized_percent_switch_7_link_0: 0 bw: 640000 base_latency: 1 + links_utilized_percent_switch_7_link_1: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_7_link_0_Response_Data: 93225 6712200 [ 0 93225 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_0_Writeback_Control: 93246 745968 [ 0 0 93246 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_1_Control: 93231 745848 [ 93231 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_1_Data: 86453 6224616 [ 86453 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_7_link_1_Response_Data: 6799 489528 [ 0 6799 0 0 0 0 0 0 0 0 ] base_latency: 1 switch_8_inlinks: 2 switch_8_outlinks: 2 -links_utilized_percent_switch_8: 0.687242 - links_utilized_percent_switch_8_link_0: 0.274971 bw: 640000 base_latency: 1 - links_utilized_percent_switch_8_link_1: 1.09951 bw: 160000 base_latency: 1 +links_utilized_percent_switch_8: 0.386975 + links_utilized_percent_switch_8_link_0: 0.15479 bw: 640000 base_latency: 1 + links_utilized_percent_switch_8_link_1: 0.61916 bw: 160000 base_latency: 1 - outgoing_messages_switch_8_link_0_Control: 745807 5966456 [ 745807 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_8_link_0_Data: 691768 49807296 [ 691768 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_8_link_1_Response_Data: 691499 49787928 [ 0 691499 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_8_link_1_Writeback_Control: 745884 5967072 [ 0 0 745884 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_0_Control: 748631 5989048 [ 748631 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_0_Data: 748628 53901216 [ 748628 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_1_Response_Data: 748630 53901360 [ 0 748630 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_8_link_1_Writeback_Control: 748626 5989008 [ 0 0 748626 0 0 0 0 0 0 0 ] base_latency: 1 switch_9_inlinks: 2 switch_9_outlinks: 2 @@ -616,148 +578,106 @@ links_utilized_percent_switch_9: 0 switch_10_inlinks: 10 switch_10_outlinks: 10 -links_utilized_percent_switch_10: 0.227638 - links_utilized_percent_switch_10_link_0: 0.14703 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_1: 0.147121 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_2: 0.147012 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_3: 0.147077 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_4: 0.147049 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_5: 0.147036 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_6: 0.147092 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_7: 0.147078 bw: 160000 base_latency: 1 - links_utilized_percent_switch_10_link_8: 1.09988 bw: 160000 base_latency: 1 +links_utilized_percent_switch_10: 0.123832 + links_utilized_percent_switch_10_link_0: 0.61916 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_1: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_2: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_3: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_4: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_5: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_6: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_7: 0 bw: 160000 base_latency: 1 + links_utilized_percent_switch_10_link_8: 0.619159 bw: 160000 base_latency: 1 links_utilized_percent_switch_10_link_9: 0 bw: 160000 base_latency: 1 - outgoing_messages_switch_10_link_0_Response_Data: 93195 6710040 [ 0 93195 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_0_Writeback_Control: 93211 745688 [ 0 0 93211 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_1_Response_Data: 93252 6714144 [ 0 93252 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_1_Writeback_Control: 93276 746208 [ 0 0 93276 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_2_Response_Data: 93184 6709248 [ 0 93184 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_2_Writeback_Control: 93192 745536 [ 0 0 93192 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_3_Response_Data: 93224 6712128 [ 0 93224 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_3_Writeback_Control: 93249 745992 [ 0 0 93249 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_4_Response_Data: 93206 6710832 [ 0 93206 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_4_Writeback_Control: 93228 745824 [ 0 0 93228 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_5_Response_Data: 93198 6710256 [ 0 93198 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_5_Writeback_Control: 93222 745776 [ 0 0 93222 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_6_Response_Data: 93233 6712776 [ 0 93233 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_6_Writeback_Control: 93260 746080 [ 0 0 93260 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_7_Response_Data: 93225 6712200 [ 0 93225 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_7_Writeback_Control: 93246 745968 [ 0 0 93246 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_8_Control: 745807 5966456 [ 745807 0 0 0 0 0 0 0 0 0 ] base_latency: 1 - outgoing_messages_switch_10_link_8_Data: 691768 49807296 [ 691768 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_0_Response_Data: 748630 53901360 [ 0 748630 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_0_Writeback_Control: 748626 5989008 [ 0 0 748626 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_8_Control: 748631 5989048 [ 748631 0 0 0 0 0 0 0 0 0 ] base_latency: 1 + outgoing_messages_switch_10_link_8_Data: 748628 53901216 [ 748628 0 0 0 0 0 0 0 0 0 ] base_latency: 1 l1u_0 cache stats: - l1u_0_total_misses: 93208 - l1u_0_total_demand_misses: 93208 + l1u_0_total_misses: 748631 + l1u_0_total_demand_misses: 748631 l1u_0_total_prefetches: 0 l1u_0_total_sw_prefetches: 0 l1u_0_total_hw_prefetches: 0 l1u_0_misses_per_transaction: inf - l1u_0_request_type_LD: 65.0406% - l1u_0_request_type_ST: 34.9594% + l1u_0_request_type_LD: 65.0336% + l1u_0_request_type_ST: 34.9664% - l1u_0_access_mode_type_SupervisorMode: 93208 100% - l1u_0_request_size: [binsize: log2 max: 1 count: 93208 average: 1 | standard deviation: 0 | 0 93208 ] + l1u_0_access_mode_type_SupervisorMode: 748631 100% + l1u_0_request_size: [binsize: log2 max: 1 count: 748631 average: 1 | standard deviation: 0 | 0 748631 ] l1u_1 cache stats: - l1u_1_total_misses: 93262 - l1u_1_total_demand_misses: 93262 + l1u_1_total_misses: 0 + l1u_1_total_demand_misses: 0 l1u_1_total_prefetches: 0 l1u_1_total_sw_prefetches: 0 l1u_1_total_hw_prefetches: 0 - l1u_1_misses_per_transaction: inf + l1u_1_misses_per_transaction: nan - l1u_1_request_type_LD: 65.1348% - l1u_1_request_type_ST: 34.8652% - - l1u_1_access_mode_type_SupervisorMode: 93262 100% - l1u_1_request_size: [binsize: log2 max: 1 count: 93262 average: 1 | standard deviation: 0 | 0 93262 ] + l1u_1_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_2 cache stats: - l1u_2_total_misses: 93199 - l1u_2_total_demand_misses: 93199 + l1u_2_total_misses: 0 + l1u_2_total_demand_misses: 0 l1u_2_total_prefetches: 0 l1u_2_total_sw_prefetches: 0 l1u_2_total_hw_prefetches: 0 - l1u_2_misses_per_transaction: inf + l1u_2_misses_per_transaction: nan - l1u_2_request_type_LD: 65.0157% - l1u_2_request_type_ST: 34.9843% - - l1u_2_access_mode_type_SupervisorMode: 93199 100% - l1u_2_request_size: [binsize: log2 max: 1 count: 93199 average: 1 | standard deviation: 0 | 0 93199 ] + l1u_2_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_3 cache stats: - l1u_3_total_misses: 93230 - l1u_3_total_demand_misses: 93230 + l1u_3_total_misses: 0 + l1u_3_total_demand_misses: 0 l1u_3_total_prefetches: 0 l1u_3_total_sw_prefetches: 0 l1u_3_total_hw_prefetches: 0 - l1u_3_misses_per_transaction: inf + l1u_3_misses_per_transaction: nan - l1u_3_request_type_LD: 65.0542% - l1u_3_request_type_ST: 34.9458% - - l1u_3_access_mode_type_SupervisorMode: 93230 100% - l1u_3_request_size: [binsize: log2 max: 1 count: 93230 average: 1 | standard deviation: 0 | 0 93230 ] + l1u_3_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_4 cache stats: - l1u_4_total_misses: 93219 - l1u_4_total_demand_misses: 93219 + l1u_4_total_misses: 0 + l1u_4_total_demand_misses: 0 l1u_4_total_prefetches: 0 l1u_4_total_sw_prefetches: 0 l1u_4_total_hw_prefetches: 0 - l1u_4_misses_per_transaction: inf + l1u_4_misses_per_transaction: nan - l1u_4_request_type_LD: 65.2142% - l1u_4_request_type_ST: 34.7858% - - l1u_4_access_mode_type_SupervisorMode: 93219 100% - l1u_4_request_size: [binsize: log2 max: 1 count: 93219 average: 1 | standard deviation: 0 | 0 93219 ] + l1u_4_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_5 cache stats: - l1u_5_total_misses: 93213 - l1u_5_total_demand_misses: 93213 + l1u_5_total_misses: 0 + l1u_5_total_demand_misses: 0 l1u_5_total_prefetches: 0 l1u_5_total_sw_prefetches: 0 l1u_5_total_hw_prefetches: 0 - l1u_5_misses_per_transaction: inf + l1u_5_misses_per_transaction: nan - l1u_5_request_type_LD: 64.8976% - l1u_5_request_type_ST: 35.1024% - - l1u_5_access_mode_type_SupervisorMode: 93213 100% - l1u_5_request_size: [binsize: log2 max: 1 count: 93213 average: 1 | standard deviation: 0 | 0 93213 ] + l1u_5_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_6 cache stats: - l1u_6_total_misses: 93245 - l1u_6_total_demand_misses: 93245 + l1u_6_total_misses: 0 + l1u_6_total_demand_misses: 0 l1u_6_total_prefetches: 0 l1u_6_total_sw_prefetches: 0 l1u_6_total_hw_prefetches: 0 - l1u_6_misses_per_transaction: inf + l1u_6_misses_per_transaction: nan - l1u_6_request_type_LD: 65.033% - l1u_6_request_type_ST: 34.967% - - l1u_6_access_mode_type_SupervisorMode: 93245 100% - l1u_6_request_size: [binsize: log2 max: 1 count: 93245 average: 1 | standard deviation: 0 | 0 93245 ] + l1u_6_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] l1u_7 cache stats: - l1u_7_total_misses: 93231 - l1u_7_total_demand_misses: 93231 + l1u_7_total_misses: 0 + l1u_7_total_demand_misses: 0 l1u_7_total_prefetches: 0 l1u_7_total_sw_prefetches: 0 l1u_7_total_hw_prefetches: 0 - l1u_7_misses_per_transaction: inf + l1u_7_misses_per_transaction: nan - l1u_7_request_type_LD: 64.9805% - l1u_7_request_type_ST: 35.0195% - - l1u_7_access_mode_type_SupervisorMode: 93231 100% - l1u_7_request_size: [binsize: log2 max: 1 count: 93231 average: 1 | standard deviation: 0 | 0 93231 ] + l1u_7_request_size: [binsize: log2 max: 0 count: 0 average: NaN |standard deviation: NaN | 0 ] --- DMA 0 --- - Event Counts - @@ -776,24 +696,24 @@ BUSY_WR Ack 0 <-- --- Directory 0 --- - Event Counts - -GETX 7494804 +GETX 748631 GETS 0 -PUTX 691343 -PUTX_NotOwner 425 +PUTX 748628 +PUTX_NotOwner 0 DMA_READ 0 DMA_WRITE 0 -Memory_Data 691500 -Memory_Ack 691241 +Memory_Data 748630 +Memory_Ack 748626 - Transitions - -I GETX 691586 +I GETX 748631 I PUTX_NotOwner 0 <-- I DMA_READ 0 <-- I DMA_WRITE 0 <-- -M GETX 54218 -M PUTX 691343 -M PUTX_NotOwner 425 +M GETX 0 <-- +M PUTX 748628 +M PUTX_NotOwner 0 <-- M DMA_READ 0 <-- M DMA_WRITE 0 <-- @@ -809,21 +729,21 @@ M_DWRI Memory_Ack 0 <-- M_DRDI GETX 0 <-- M_DRDI Memory_Ack 0 <-- -IM GETX 3180524 +IM GETX 0 <-- IM GETS 0 <-- IM PUTX 0 <-- IM PUTX_NotOwner 0 <-- IM DMA_READ 0 <-- IM DMA_WRITE 0 <-- -IM Memory_Data 691500 +IM Memory_Data 748630 -MI GETX 3568476 +MI GETX 0 <-- MI GETS 0 <-- MI PUTX 0 <-- MI PUTX_NotOwner 0 <-- MI DMA_READ 0 <-- MI DMA_WRITE 0 <-- -MI Memory_Ack 691241 +MI Memory_Ack 748626 ID GETX 0 <-- ID GETS 0 <-- @@ -843,289 +763,289 @@ ID_W Memory_Ack 0 <-- --- L1Cache 0 --- - Event Counts - -Load 60623 +Load 487449 Ifetch 0 -Store 32585 -Data 93195 -Fwd_GETX 6749 +Store 262120 +Data 748630 +Fwd_GETX 0 Inv 0 -Replacement 93176 -Writeback_Ack 86414 -Writeback_Nack 48 +Replacement 748628 +Writeback_Ack 748626 +Writeback_Nack 0 - Transitions - -I Load 60623 +I Load 486862 I Ifetch 0 <-- -I Store 32585 +I Store 261769 I Inv 0 <-- -I Replacement 6700 +I Replacement 0 <-- -II Writeback_Nack 48 +II Writeback_Nack 0 <-- -M Load 0 <-- +M Load 587 M Ifetch 0 <-- -M Store 0 <-- -M Fwd_GETX 6701 +M Store 351 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86476 +M Replacement 748628 -MI Fwd_GETX 48 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86414 +MI Writeback_Ack 748626 -IS Data 60616 +IS Data 486861 -IM Data 32579 +IM Data 261769 --- L1Cache 1 --- - Event Counts - -Load 60746 +Load 0 Ifetch 0 -Store 32516 -Data 93252 -Fwd_GETX 6782 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93230 -Writeback_Ack 86438 -Writeback_Nack 56 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60746 +I Load 0 <-- I Ifetch 0 <-- -I Store 32516 +I Store 0 <-- I Inv 0 <-- -I Replacement 6725 +I Replacement 0 <-- -II Writeback_Nack 56 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6726 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86505 +M Replacement 0 <-- -MI Fwd_GETX 56 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86438 +MI Writeback_Ack 0 <-- -IS Data 60738 +IS Data 0 <-- -IM Data 32514 +IM Data 0 <-- --- L1Cache 2 --- - Event Counts - -Load 60594 +Load 0 Ifetch 0 -Store 32605 -Data 93184 -Fwd_GETX 6880 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93167 -Writeback_Ack 86271 -Writeback_Nack 41 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60594 +I Load 0 <-- I Ifetch 0 <-- -I Store 32605 +I Store 0 <-- I Inv 0 <-- -I Replacement 6838 +I Replacement 0 <-- -II Writeback_Nack 41 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6839 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86329 +M Replacement 0 <-- -MI Fwd_GETX 41 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86271 +MI Writeback_Ack 0 <-- -IS Data 60583 +IS Data 0 <-- -IM Data 32601 +IM Data 0 <-- --- L1Cache 3 --- - Event Counts - -Load 60650 +Load 0 Ifetch 0 -Store 32580 -Data 93224 -Fwd_GETX 6766 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93198 -Writeback_Ack 86421 -Writeback_Nack 62 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60650 +I Load 0 <-- I Ifetch 0 <-- -I Store 32580 +I Store 0 <-- I Inv 0 <-- -I Replacement 6703 +I Replacement 0 <-- -II Writeback_Nack 62 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6704 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86495 +M Replacement 0 <-- -MI Fwd_GETX 62 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86421 +MI Writeback_Ack 0 <-- -IS Data 60647 +IS Data 0 <-- -IM Data 32577 +IM Data 0 <-- --- L1Cache 4 --- - Event Counts - -Load 60792 +Load 0 Ifetch 0 -Store 32427 -Data 93206 -Fwd_GETX 6958 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93187 -Writeback_Ack 86214 -Writeback_Nack 56 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60792 +I Load 0 <-- I Ifetch 0 <-- -I Store 32427 +I Store 0 <-- I Inv 0 <-- -I Replacement 6902 +I Replacement 0 <-- -II Writeback_Nack 56 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6902 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86285 +M Replacement 0 <-- -MI Fwd_GETX 56 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86214 +MI Writeback_Ack 0 <-- -IS Data 60783 +IS Data 0 <-- -IM Data 32423 +IM Data 0 <-- --- L1Cache 5 --- - Event Counts - -Load 60493 +Load 0 Ifetch 0 -Store 32720 -Data 93198 -Fwd_GETX 6597 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93181 -Writeback_Ack 86569 -Writeback_Nack 56 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60493 +I Load 0 <-- I Ifetch 0 <-- -I Store 32720 +I Store 0 <-- I Inv 0 <-- -I Replacement 6541 +I Replacement 0 <-- -II Writeback_Nack 56 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6541 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86640 +M Replacement 0 <-- -MI Fwd_GETX 56 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86569 +MI Writeback_Ack 0 <-- -IS Data 60486 +IS Data 0 <-- -IM Data 32712 +IM Data 0 <-- --- L1Cache 6 --- - Event Counts - -Load 60640 +Load 0 Ifetch 0 -Store 32605 -Data 93233 -Fwd_GETX 6687 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93213 -Writeback_Ack 86519 -Writeback_Nack 54 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60640 +I Load 0 <-- I Ifetch 0 <-- -I Store 32605 +I Store 0 <-- I Inv 0 <-- -I Replacement 6628 +I Replacement 0 <-- -II Writeback_Nack 54 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6633 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86585 +M Replacement 0 <-- -MI Fwd_GETX 54 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86519 +MI Writeback_Ack 0 <-- -IS Data 60634 +IS Data 0 <-- -IM Data 32599 +IM Data 0 <-- --- L1Cache 7 --- - Event Counts - -Load 60582 +Load 0 Ifetch 0 -Store 32649 -Data 93225 -Fwd_GETX 6799 +Store 0 +Data 0 +Fwd_GETX 0 Inv 0 -Replacement 93199 -Writeback_Ack 86395 -Writeback_Nack 52 +Replacement 0 +Writeback_Ack 0 +Writeback_Nack 0 - Transitions - -I Load 60582 +I Load 0 <-- I Ifetch 0 <-- -I Store 32649 +I Store 0 <-- I Inv 0 <-- -I Replacement 6746 +I Replacement 0 <-- -II Writeback_Nack 52 +II Writeback_Nack 0 <-- M Load 0 <-- M Ifetch 0 <-- M Store 0 <-- -M Fwd_GETX 6747 +M Fwd_GETX 0 <-- M Inv 0 <-- -M Replacement 86453 +M Replacement 0 <-- -MI Fwd_GETX 52 +MI Fwd_GETX 0 <-- MI Inv 0 <-- -MI Writeback_Ack 86395 +MI Writeback_Ack 0 <-- -IS Data 60577 +IS Data 0 <-- -IM Data 32648 +IM Data 0 <-- diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr index 5a5c8990a0..8fe2d4613b 100755 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simerr @@ -1,76 +1,76 @@ -["-r", "tests/configs/../../src/mem/ruby/config/MI_example-homogeneous.rb", "-p", "8", "-m", "1", "-s", "1024"] +["-r", "tests/configs/../../src/mem/ruby/config/MI_example-homogeneous.rb", "-p", "8", "-m", "1", "-s", "1024", "-C", "256", "-A", "2", "-D", "1"] print config: 1 -system.cpu4: completed 10000 read accesses @3675185 -system.cpu2: completed 10000 read accesses @3684370 -system.cpu1: completed 10000 read accesses @3684384 -system.cpu5: completed 10000 read accesses @3692230 -system.cpu7: completed 10000 read accesses @3697989 -system.cpu3: completed 10000 read accesses @3700408 -system.cpu0: completed 10000 read accesses @3740018 -system.cpu6: completed 10000 read accesses @3740090 -system.cpu4: completed 20000 read accesses @6800644 -system.cpu5: completed 20000 read accesses @6817332 -system.cpu1: completed 20000 read accesses @6845862 -system.cpu7: completed 20000 read accesses @6846102 -system.cpu3: completed 20000 read accesses @6846189 -system.cpu6: completed 20000 read accesses @6869288 -system.cpu0: completed 20000 read accesses @6871457 -system.cpu2: completed 20000 read accesses @6873399 -system.cpu5: completed 30000 read accesses @9907427 -system.cpu1: completed 30000 read accesses @9942140 -system.cpu4: completed 30000 read accesses @9951770 -system.cpu3: completed 30000 read accesses @9955002 -system.cpu2: completed 30000 read accesses @9959638 -system.cpu7: completed 30000 read accesses @10014906 -system.cpu6: completed 30000 read accesses @10028154 -system.cpu0: completed 30000 read accesses @10058436 -system.cpu3: completed 40000 read accesses @13045316 -system.cpu5: completed 40000 read accesses @13050166 -system.cpu4: completed 40000 read accesses @13057566 -system.cpu6: completed 40000 read accesses @13079138 -system.cpu2: completed 40000 read accesses @13081014 -system.cpu1: completed 40000 read accesses @13142214 -system.cpu0: completed 40000 read accesses @13144987 -system.cpu7: completed 40000 read accesses @13150846 -system.cpu3: completed 50000 read accesses @16142041 -system.cpu5: completed 50000 read accesses @16172122 -system.cpu6: completed 50000 read accesses @16220230 -system.cpu2: completed 50000 read accesses @16227420 -system.cpu4: completed 50000 read accesses @16237330 -system.cpu0: completed 50000 read accesses @16246676 -system.cpu1: completed 50000 read accesses @16278708 -system.cpu7: completed 50000 read accesses @16279864 -system.cpu3: completed 60000 read accesses @19234712 -system.cpu0: completed 60000 read accesses @19348851 -system.cpu6: completed 60000 read accesses @19370476 -system.cpu4: completed 60000 read accesses @19371128 -system.cpu5: completed 60000 read accesses @19373426 -system.cpu2: completed 60000 read accesses @19377688 -system.cpu7: completed 60000 read accesses @19379274 -system.cpu1: completed 60000 read accesses @19415186 -system.cpu3: completed 70000 read accesses @22337696 -system.cpu0: completed 70000 read accesses @22429460 -system.cpu4: completed 70000 read accesses @22492782 -system.cpu6: completed 70000 read accesses @22501157 -system.cpu2: completed 70000 read accesses @22508620 -system.cpu7: completed 70000 read accesses @22510770 -system.cpu5: completed 70000 read accesses @22526762 -system.cpu1: completed 70000 read accesses @22535410 -system.cpu3: completed 80000 read accesses @25425072 -system.cpu0: completed 80000 read accesses @25533098 -system.cpu1: completed 80000 read accesses @25591166 -system.cpu7: completed 80000 read accesses @25605790 -system.cpu5: completed 80000 read accesses @25629716 -system.cpu6: completed 80000 read accesses @25648430 -system.cpu4: completed 80000 read accesses @25658464 -system.cpu2: completed 80000 read accesses @25694944 -system.cpu3: completed 90000 read accesses @28554280 -system.cpu1: completed 90000 read accesses @28698524 -system.cpu0: completed 90000 read accesses @28699664 -system.cpu7: completed 90000 read accesses @28703590 -system.cpu4: completed 90000 read accesses @28740026 -system.cpu5: completed 90000 read accesses @28744438 -system.cpu2: completed 90000 read accesses @28783998 -system.cpu6: completed 90000 read accesses @28784829 -system.cpu3: completed 100000 read accesses @31693010 +system.cpu7: completed 10000 read accesses @7023642 +system.cpu5: completed 10000 read accesses @7028438 +system.cpu3: completed 10000 read accesses @7034626 +system.cpu1: completed 10000 read accesses @7035790 +system.cpu2: completed 10000 read accesses @7062558 +system.cpu6: completed 10000 read accesses @7078882 +system.cpu0: completed 10000 read accesses @7080455 +system.cpu4: completed 10000 read accesses @7095500 +system.cpu1: completed 20000 read accesses @12915324 +system.cpu3: completed 20000 read accesses @12958052 +system.cpu5: completed 20000 read accesses @12993554 +system.cpu2: completed 20000 read accesses @13010879 +system.cpu4: completed 20000 read accesses @13014760 +system.cpu6: completed 20000 read accesses @13031684 +system.cpu7: completed 20000 read accesses @13051162 +system.cpu0: completed 20000 read accesses @13128234 +system.cpu3: completed 30000 read accesses @18784435 +system.cpu1: completed 30000 read accesses @18859194 +system.cpu5: completed 30000 read accesses @18903265 +system.cpu7: completed 30000 read accesses @18952860 +system.cpu4: completed 30000 read accesses @18981745 +system.cpu6: completed 30000 read accesses @18987772 +system.cpu0: completed 30000 read accesses @18993365 +system.cpu2: completed 30000 read accesses @18994061 +system.cpu3: completed 40000 read accesses @24748372 +system.cpu2: completed 40000 read accesses @24758090 +system.cpu1: completed 40000 read accesses @24768884 +system.cpu7: completed 40000 read accesses @24891866 +system.cpu0: completed 40000 read accesses @24907680 +system.cpu6: completed 40000 read accesses @24933908 +system.cpu5: completed 40000 read accesses @24949374 +system.cpu4: completed 40000 read accesses @24963853 +system.cpu3: completed 50000 read accesses @30655893 +system.cpu2: completed 50000 read accesses @30705287 +system.cpu1: completed 50000 read accesses @30752130 +system.cpu0: completed 50000 read accesses @30795942 +system.cpu5: completed 50000 read accesses @30809328 +system.cpu7: completed 50000 read accesses @30857254 +system.cpu6: completed 50000 read accesses @30935432 +system.cpu4: completed 50000 read accesses @30960853 +system.cpu3: completed 60000 read accesses @36647735 +system.cpu2: completed 60000 read accesses @36648110 +system.cpu1: completed 60000 read accesses @36690971 +system.cpu7: completed 60000 read accesses @36746000 +system.cpu5: completed 60000 read accesses @36746430 +system.cpu0: completed 60000 read accesses @36840602 +system.cpu6: completed 60000 read accesses @36900332 +system.cpu4: completed 60000 read accesses @36954562 +system.cpu2: completed 70000 read accesses @42614948 +system.cpu1: completed 70000 read accesses @42616200 +system.cpu5: completed 70000 read accesses @42679549 +system.cpu7: completed 70000 read accesses @42707038 +system.cpu3: completed 70000 read accesses @42725206 +system.cpu0: completed 70000 read accesses @42774272 +system.cpu6: completed 70000 read accesses @42850956 +system.cpu4: completed 70000 read accesses @42872700 +system.cpu5: completed 80000 read accesses @48577066 +system.cpu7: completed 80000 read accesses @48608169 +system.cpu2: completed 80000 read accesses @48616581 +system.cpu1: completed 80000 read accesses @48637808 +system.cpu0: completed 80000 read accesses @48726360 +system.cpu3: completed 80000 read accesses @48754087 +system.cpu4: completed 80000 read accesses @48848416 +system.cpu6: completed 80000 read accesses @48849321 +system.cpu5: completed 90000 read accesses @54536042 +system.cpu0: completed 90000 read accesses @54536954 +system.cpu7: completed 90000 read accesses @54554538 +system.cpu1: completed 90000 read accesses @54575168 +system.cpu2: completed 90000 read accesses @54648034 +system.cpu3: completed 90000 read accesses @54719200 +system.cpu6: completed 90000 read accesses @54807510 +system.cpu4: completed 90000 read accesses @54840954 +system.cpu1: completed 100000 read accesses @60455258 hack: be nice to actually delete the event here diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout index 8b71905663..96bce5ceca 100755 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/simout @@ -1,3 +1,5 @@ +Redirecting stdout to build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby/simout +Redirecting stderr to build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby/simerr M5 Simulator System Copyright (c) 2001-2008 @@ -5,11 +7,11 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Nov 3 2009 14:40:57 -M5 revision 0e5037cecaf7 6707 default tip -M5 started Nov 3 2009 14:41:01 -M5 executing on phenom +M5 compiled Nov 18 2009 16:36:52 +M5 revision c1d634e76817 6798 default qtip tip brad/ruby_memtest_refresh +M5 started Nov 18 2009 16:37:05 +M5 executing on cabr0354 command line: build/ALPHA_SE/m5.fast -d build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby -re tests/run.py build/ALPHA_SE/tests/fast/quick/50.memtest/alpha/linux/memtest-ruby Global frequency set at 1000000000000 ticks per second info: Entering event queue @ 0. Starting simulation... -Exiting @ tick 31693010 because maximum number of loads reached +Exiting @ tick 60455258 because maximum number of loads reached diff --git a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt index 977e6ebbe6..9b0c245276 100644 --- a/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt +++ b/tests/quick/50.memtest/ref/alpha/linux/memtest-ruby/stats.txt @@ -1,34 +1,34 @@ ---------- Begin Simulation Statistics ---------- -host_mem_usage 1501368 # Number of bytes of host memory used -host_seconds 892.41 # Real time elapsed on the host -host_tick_rate 35514 # Simulator tick rate (ticks/s) +host_mem_usage 2438776 # Number of bytes of host memory used +host_seconds 3924.24 # Real time elapsed on the host +host_tick_rate 15406 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_seconds 0.000032 # Number of seconds simulated -sim_ticks 31693010 # Number of ticks simulated +sim_seconds 0.000060 # Number of seconds simulated +sim_ticks 60455258 # Number of ticks simulated system.cpu0.num_copies 0 # number of copy accesses completed -system.cpu0.num_reads 99568 # number of read accesses completed -system.cpu0.num_writes 53636 # number of write accesses completed +system.cpu0.num_reads 99982 # number of read accesses completed +system.cpu0.num_writes 53168 # number of write accesses completed system.cpu1.num_copies 0 # number of copy accesses completed -system.cpu1.num_reads 99545 # number of read accesses completed -system.cpu1.num_writes 53439 # number of write accesses completed +system.cpu1.num_reads 100000 # number of read accesses completed +system.cpu1.num_writes 53657 # number of write accesses completed system.cpu2.num_copies 0 # number of copy accesses completed -system.cpu2.num_reads 99287 # number of read accesses completed -system.cpu2.num_writes 53468 # number of write accesses completed +system.cpu2.num_reads 99758 # number of read accesses completed +system.cpu2.num_writes 53630 # number of write accesses completed system.cpu3.num_copies 0 # number of copy accesses completed -system.cpu3.num_reads 100000 # number of read accesses completed -system.cpu3.num_writes 53560 # number of write accesses completed +system.cpu3.num_reads 99707 # number of read accesses completed +system.cpu3.num_writes 53628 # number of write accesses completed system.cpu4.num_copies 0 # number of copy accesses completed -system.cpu4.num_reads 99582 # number of read accesses completed -system.cpu4.num_writes 53929 # number of write accesses completed +system.cpu4.num_reads 99425 # number of read accesses completed +system.cpu4.num_writes 53969 # number of write accesses completed system.cpu5.num_copies 0 # number of copy accesses completed -system.cpu5.num_reads 99543 # number of read accesses completed -system.cpu5.num_writes 53703 # number of write accesses completed +system.cpu5.num_reads 99810 # number of read accesses completed +system.cpu5.num_writes 53444 # number of write accesses completed system.cpu6.num_copies 0 # number of copy accesses completed -system.cpu6.num_reads 99253 # number of read accesses completed -system.cpu6.num_writes 53497 # number of write accesses completed +system.cpu6.num_reads 99532 # number of read accesses completed +system.cpu6.num_writes 53907 # number of write accesses completed system.cpu7.num_copies 0 # number of copy accesses completed -system.cpu7.num_reads 99640 # number of read accesses completed -system.cpu7.num_writes 53676 # number of write accesses completed +system.cpu7.num_reads 99819 # number of read accesses completed +system.cpu7.num_writes 53668 # number of write accesses completed ---------- End Simulation Statistics ----------